diff --git a/.github/workflows/admin.yaml b/.github/workflows/admin.yaml index 239535bbb..291e6f9e6 100644 --- a/.github/workflows/admin.yaml +++ b/.github/workflows/admin.yaml @@ -13,8 +13,8 @@ on: workflow_call: jobs: - eslint: - name: ESLint + lint: + name: Lint runs-on: ubuntu-latest steps: - uses: shopware/github-actions/setup-extension@main @@ -34,6 +34,7 @@ jobs: - run: | composer -d custom/plugins/${{ github.event.repository.name }} run admin:install composer -d custom/plugins/${{ github.event.repository.name }} run admin:lint + composer -d custom/plugins/${{ github.event.repository.name }} run admin:format stylelint: name: Stylelint diff --git a/.github/workflows/check-pr-title.yml b/.github/workflows/check-pr-title.yml new file mode 100644 index 000000000..6da327569 --- /dev/null +++ b/.github/workflows/check-pr-title.yml @@ -0,0 +1,33 @@ +name: Check PR title + +on: + pull_request: + types: + - opened + - reopened + - edited + - synchronize + +permissions: + pull-requests: read + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # 6.1.1 + with: + types: | + feat + fix + chore + docs + style + refactor + perf + test + build + ci + revert + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/integration.yaml b/.github/workflows/integration.yaml index 4d8fd2acd..7bef6fd32 100644 --- a/.github/workflows/integration.yaml +++ b/.github/workflows/integration.yaml @@ -55,7 +55,7 @@ jobs: } - name: Import SW5 TestData DB working-directory: custom/plugins/${{ github.event.repository.name }}/tests - run: mysql -uroot < testData/sw55.sql + run: mysql -uroot < _fixtures/database/sw55.sql - name: Run PHPUnit working-directory: custom/plugins/${{ github.event.repository.name }} run: php -d pcov.enabled=1 -d pcov.directory=${PWD} -d pcov.exclude='~(vendor|tests|node_modules)~' ${GITHUB_WORKSPACE}/vendor/bin/phpunit --configuration phpunit.xml.dist @@ -118,7 +118,7 @@ jobs: run: | composer run build:js:admin cd custom/plugins/${{ github.event.repository.name }}/tests - mysql -uroot < testData/sw55.sql + mysql -uroot < _fixtures/database/sw55.sql - name: Install playwright working-directory: custom/plugins/${{ github.event.repository.name }}/tests/acceptance run: | diff --git a/.gitignore b/.gitignore index 5d53cb79f..ba9a778e3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,32 @@ -.idea -.vscode -coverage/ -.phpunit.cache -.phpunit.result.cache -vendor -node_modules -phpstan.neon +# ide +.idea/ +.vscode/ + +# os +.DS_Store + +# node +node_modules/ *.hot-update.js -/var/ + +# php +vendor/ +phpstan.neon composer.lock -src/Resources/public/administration/ +.phpunit.cache +.phpunit.result.cache + +# tests +coverage/ + +# build src/Resources/public/static/ +src/Resources/public/administration/ +src/Resources/app/administration/.tmp + +# runtime +/var/ .env + +# plugin /migration_assistant.cache diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index 1657d96f2..000000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,199 +0,0 @@ -variables: - PLUGIN_NAME: SwagMigrationAssistant - PLATFORM_MIN_VERSION: 'v6.6.1.0' - PLATFORM_DEFAULT_VERSION: 'trunk' - PLATFORM_BRANCH: $PLATFORM_DEFAULT_VERSION - DEV_IMAGE: - value: ${CI_REGISTRY}/infrastructure/docker-base/ci-build:latest - NODE_VERSION: 20 - -include: - - project: 'shopware/6/product/platform' - ref: 'trunk' - file: '.gitlab/templates/plugin.yml' -# - component: gitlab.shopware.com/infrastructure/ci-component-library/kaniko-amd64@trunk -# inputs: -# job-suffix: "" -# stage: E2E -# destination-image: "${CI_REGISTRY_IMAGE}/ci-e2e" -# destination-tag: "${PLATFORM_BRANCH}-${CI_PIPELINE_ID}" -# dockerfile: .gitlab/Dockerfile -# enable-scan: "false" -# cache: "false" -# build-arg: "BASE_IMAGE=$PLATFORM_BASE_IMAGE" -# extra-args: "--build-arg CI_JOB_TOKEN=$CI_JOB_TOKEN" - -Danger: - stage: test - image: - name: ghcr.io/shyim/danger-php:latest - entrypoint: [ "" ] - rules: - - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' - before_script: [ ] - script: - - danger ci - -ecs: - stage: test - script: - - composer ecs - -Eslint (administration): - stage: test - variables: - APP_ENV: prod - ADMIN_PATH: $CI_PROJECT_DIR/src/Administration/Resources/app/administration - STOREFRONT_PATH: $CI_PROJECT_DIR/src/Storefront/Resources/app/storefront - script: - - '(cd $ADMIN_PATH && npm ci)' - - $CI_PROJECT_DIR/bin/console framework:schema -s 'entity-schema' $ADMIN_PATH/test/_mocks_/entity-schema.json - - npm --prefix $ADMIN_PATH run unit-setup - - composer admin:install - - composer admin:lint - -jest (administration): - rules: - # exists does not support variables, so we cannot use ${PLUGIN_SOURCE_DIR} here - - exists: - - tests/Jest/jest.config.js - variables: - APP_ENV: prod - ADMIN_PATH: $CI_PROJECT_DIR/src/Administration/Resources/app/administration - STOREFRONT_PATH: $CI_PROJECT_DIR/src/Storefront/Resources/app/storefront - script: - - '(cd $ADMIN_PATH && npm ci)' - - $CI_PROJECT_DIR/bin/console framework:schema -s 'entity-schema' $ADMIN_PATH/test/_mocks_/entity-schema.json - - npm --prefix $ADMIN_PATH run unit-setup - - composer admin:install - - composer admin:unit -- --ci - coverage: '/^\s?All files[^|]*\|[^|]*\s+([\d\.]+)/' - artifacts: - paths: - # allow inspection of the coverage report, otherwise it's not accessible - - custom/plugins/SwagMigrationAssistant/coverage/cobertura-coverage.xml - reports: - junit: - - custom/plugins/SwagMigrationAssistant/coverage/junit.xml - coverage_report: - coverage_format: cobertura - path: custom/plugins/SwagMigrationAssistant/coverage/cobertura-coverage.xml - -phpunit: - script: - - apt-get update && apt-get --assume-yes install default-mysql-client - - cd tests - - cd - - - mysql --skip_ssl -uroot -p"$MYSQL_ROOT_PASSWORD" --host mysql < tests/testData/sw55.sql - - php - -d pcov.enabled=1 -d pcov.directory=$PWD -d pcov.exclude='~(vendor|tests|node_modules)~' - ${PROJECT_ROOT}/vendor/bin/phpunit - --configuration phpunit.xml.dist - --log-junit ${CI_PROJECT_DIR}/phpunit.junit.xml - --colors=never - --coverage-cobertura ${CI_PROJECT_DIR}/cobertura.xml - --coverage-text #| grep -v -E '^Shopware\\|^ Methods:' # do not output covered files lines - parallel: - matrix: - - PLATFORM_BRANCH: [ $PLATFORM_MIN_VERSION, $PLATFORM_DEFAULT_VERSION ] - -phpstan: - script: - - composer dump-autoload --dev - - composer phpstan - -smoke-test: - stage: test - needs: [] - rules: - - !reference [.rules, skip] - - when: always - script: - - cd ../../.. - - php bin/console plugin:refresh - - php bin/console plugin:install --activate --clearCache ${PLUGIN_NAME} - - php bin/console plugin:uninstall ${PLUGIN_NAME} - -# disabled acceptance test, will be active as GH Action again after move to GitHub -#build image: -# variables: -# PLATFORM_BASE_IMAGE: ${CI_REGISTRY}/shopware/6/product/platform/ci-e2e:${PLATFORM_BRANCH} -# rules: -# # not supported, the downstream pipeline should find any issues anyway -# - if: "$CI_MERGE_REQUEST_LABELS =~ /.*branch::platform::match.*/" -# when: never -# - if: "$PARENT_PIPELINE_ID" -# when: never -# - when: always -# needs: [] -# parallel: -# matrix: -# - PLATFORM_BRANCH: [ $PLATFORM_MIN_VERSION, $PLATFORM_DEFAULT_VERSION ] -# -#build image downstream: -# extends: build image -# rules: -# - if: "$PARENT_PIPELINE_ID" -# needs: -# - pipeline: $PARENT_PIPELINE_ID -# job: build image -# artifacts: false -# -#acceptance: -# image: mcr.microsoft.com/playwright:v1.44.0-jammy -# stage: E2E -# needs: -# - job: build image -# optional: true -# - job: build image downstream -# optional: true -# rules: -# # not supported, the downstream pipeline should find any issues anyway -# - if: "$CI_MERGE_REQUEST_LABELS =~ /.*branch::platform::match.*/" -# when: never -# - when: always -# services: -# - name: mysql:8.3 -# alias: database -# entrypoint: -# [ -# "sh", -# "-c", -# "docker-entrypoint.sh mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --default-authentication-plugin=mysql_native_password --sql-require-primary-key=ON", -# ] -# - name: redis:7.0 -# alias: redis -# - name: "${CI_REGISTRY_IMAGE}/ci-e2e:${PLATFORM_BRANCH}-${CI_PIPELINE_ID}" -# alias: shopware.test -# variables: -# DATABASE_URL: mysql://root:app@database:3306/root -# parallel: -# matrix: -# - PLATFORM_BRANCH: [ $PLATFORM_MIN_VERSION, $PLATFORM_DEFAULT_VERSION ] -# variables: -# # CI_DEBUG_SERVICES: "true" # This can be used to display the output of all service containers for debugging -# APP_ENV: prod -# SHOPWARE_HTTP_CACHE_ENABLED: 0 -# SHOPWARE_DISABLE_UPDATE_CHECK: "true" -# PROJECT_ROOT: /var/www/html -# MYSQL_ROOT_PASSWORD: app -# DATABASE_URL: mysql://root:app@database:3306/root -# APP_URL: http://shopware.test:8000 -# APP_DEBUG: 1 -# before_script: -# - cd tests/acceptance -# - npm ci -# script: -# - npx playwright test --workers=1 -# after_script: -# - | -# echo "Link to HTML report" -# echo "-------------------------------------------------------------------------------------------------------------------------------------------------------" -# echo "https://shopware.pages.apps.shopware.io/-/6/services/$CI_PROJECT_NAME/-/jobs/$CI_JOB_ID/artifacts/tests/acceptance/playwright-report/index.html" -# echo "-------------------------------------------------------------------------------------------------------------------------------------------------------" -# artifacts: -# expire_in: 1 day -# when: always -# paths: -# - $CI_PROJECT_DIR/tests/acceptance/test-results/* -# - $CI_PROJECT_DIR/tests/acceptance/playwright-report/* diff --git a/.gitlab/Dockerfile b/.gitlab/Dockerfile deleted file mode 100644 index 0aa0f6207..000000000 --- a/.gitlab/Dockerfile +++ /dev/null @@ -1,34 +0,0 @@ -#syntax=docker/dockerfile:1.4 - -ARG BASE_IMAGE -FROM ${BASE_IMAGE} as base-image - -FROM ghcr.io/friendsofshopware/shopware-cli:latest-php-8.2 as build -ARG CI_JOB_TOKEN - -COPY --from=base-image /var/www/html /src -WORKDIR /src - -COPY . /src/custom/plugins/SwagMigrationAssistant - -ENV COMPOSER_ALLOW_SUPERUSER=1 - -RUN /src/vendor/bin/composer -d /src/custom/plugins/SwagMigrationAssistant require --no-update 'shopware/core:*' \ - && /src/vendor/bin/composer require --no-plugins --no-scripts -o swag/migration-assistant \ - && rm -Rf /src/var/cache/* \ - && /usr/local/bin/entrypoint.sh shopware-cli project admin-build /src \ - && /usr/local/bin/entrypoint.sh shopware-cli project storefront-build --skip-theme-compile /src \ - && find . -name 'node_modules' -type d -prune -exec rm -rf '{}' + \ - && find . -name '.git' -type d -prune -exec rm -rf '{}' + \ - && rm -Rf /src/public/bundles || true - -FROM base-image - -COPY --from=build --chown=www-data --link /src /var/www/html - -USER root -RUN apk add --no-cache mysql-client - -USER www-data - -ADD .gitlab/post_install_migration_assistant.sh /usr/local/shopware/post_install.d/99_post_install_migration_assistant.sh diff --git a/.gitlab/install_test_data.php b/.gitlab/install_test_data.php deleted file mode 100644 index 25eec317c..000000000 --- a/.gitlab/install_test_data.php +++ /dev/null @@ -1,55 +0,0 @@ -\|null\}\|null\) does not accept array\{additionalData\: non\-empty\-array\\}\|array\{id\: string, connectionId\: string, oldIdentifier\: string\|null, entityUuid\: string\|null, entityValue\: string\|null, checksum\: string\|null, additionalData\: non\-empty\-array\\}\.$#' - count: 1 - path: src/Migration/Converter/Converter.php - - - - message: '#^Property SwagMigrationAssistant\\Migration\\Converter\\Converter\:\:\$mainMapping \(array\{id\: string, connectionId\: string, oldIdentifier\: string\|null, entityUuid\: string\|null, entityValue\: string\|null, checksum\: string\|null, additionalData\: array\\|null\}\|null\) does not accept array\{checksum\: string\}\|array\{id\: string, connectionId\: string, oldIdentifier\: string\|null, entityUuid\: string\|null, entityValue\: string\|null, checksum\: string, additionalData\: array\\|null\}\.$#' - count: 1 - path: src/Migration/Converter/Converter.php - - - - message: "#^swag_migration_data\\.run association has a configured autoload\\=\\=\\=true, this is forbidden for platform integrations$#" + message: '#^swag_migration_data\.run association has a configured autoload\=\=\=true, this is forbidden for platform integrations$#' + identifier: shopware.associationAutoload count: 1 path: src/Migration/Data/SwagMigrationDataDefinition.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\History\\\\HistoryService\\:\\:extractBucketInformation\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\History\\HistoryService\:\:extractBucketInformation\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/History/HistoryService.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\History\\\\HistoryService\\:\\:getGroupedLogsOfRun\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\History\\HistoryService\:\:getGroupedLogsOfRun\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/History/HistoryService.php - - message: "#^Provide more specific return type \"SwagMigrationAssistant\\\\Migration\\\\Logging\\\\SwagMigrationLoggingCollection\" over abstract one$#" + message: '#^Provide more specific return type "SwagMigrationAssistant\\Migration\\Logging\\SwagMigrationLoggingCollection" over abstract one$#' + identifier: typePerfect.narrowReturnObjectType count: 1 path: src/Migration/History/HistoryService.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\History\\\\HistoryServiceInterface\\:\\:getGroupedLogsOfRun\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\History\\HistoryServiceInterface\:\:getGroupedLogsOfRun\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/History/HistoryServiceInterface.php - - message: "#^Property SwagMigrationAssistant\\\\Migration\\\\Logging\\\\LoggingService\\:\\:\\$logging type has no value type specified in iterable type array\\.$#" + message: '#^Property SwagMigrationAssistant\\Migration\\Logging\\LoggingService\:\:\$logging type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Logging/LoggingService.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Logging\\\\SwagMigrationLoggingEntity\\:\\:getParameters\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/Migration/Logging/SwagMigrationLoggingEntity.php - - - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Logging\\\\SwagMigrationLoggingEntity\\:\\:setParameters\\(\\) has parameter \\$parameters with no value type specified in iterable type array\\.$#" - count: 1 - path: src/Migration/Logging/SwagMigrationLoggingEntity.php - - - - message: "#^Property SwagMigrationAssistant\\\\Migration\\\\Logging\\\\SwagMigrationLoggingEntity\\:\\:\\$parameters type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/Migration/Logging/SwagMigrationLoggingEntity.php - - - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Mapping\\\\MappingDeltaResult\\:\\:__construct\\(\\) has parameter \\$migrationData with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Mapping\\MappingDeltaResult\:\:__construct\(\) has parameter \$migrationData with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Mapping/MappingDeltaResult.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Mapping\\\\MappingDeltaResult\\:\\:__construct\\(\\) has parameter \\$preloadIds with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Mapping\\MappingDeltaResult\:\:__construct\(\) has parameter \$preloadIds with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Mapping/MappingDeltaResult.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Mapping\\\\MappingDeltaResult\\:\\:getMigrationData\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Mapping\\MappingDeltaResult\:\:getMigrationData\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Mapping/MappingDeltaResult.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Mapping\\\\MappingDeltaResult\\:\\:getPreloadIds\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Mapping\\MappingDeltaResult\:\:getPreloadIds\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Mapping/MappingDeltaResult.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Mapping\\\\MappingService\\:\\:getMappings\\(\\) has parameter \\$ids with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Mapping\\MappingService\:\:getMappings\(\) has parameter \$ids with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Mapping/MappingService.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Mapping\\\\MappingService\\:\\:getUuidsByEntity\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Mapping\\MappingService\:\:getUuidsByEntity\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Mapping/MappingService.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Mapping\\\\MappingService\\:\\:preloadMappings\\(\\) has parameter \\$mappingIds with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Mapping\\MappingService\:\:preloadMappings\(\) has parameter \$mappingIds with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Mapping/MappingService.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Mapping\\\\MappingService\\:\\:saveListMapping\\(\\) has parameter \\$mapping with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Mapping\\MappingService\:\:saveListMapping\(\) has parameter \$mapping with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Mapping/MappingService.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Mapping\\\\MappingService\\:\\:saveMapping\\(\\) has parameter \\$mapping with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Mapping\\MappingService\:\:saveMapping\(\) has parameter \$mapping with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Mapping/MappingService.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Mapping\\\\MappingService\\:\\:updateMapping\\(\\) has parameter \\$updateData with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Mapping\\MappingService\:\:updateMapping\(\) has parameter \$updateData with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Mapping/MappingService.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Mapping\\\\MappingService\\:\\:updateMapping\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Mapping\\MappingService\:\:updateMapping\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Mapping/MappingService.php - - message: "#^Property SwagMigrationAssistant\\\\Migration\\\\Mapping\\\\MappingService\\:\\:\\$languageData type has no value type specified in iterable type array\\.$#" + message: '#^Property SwagMigrationAssistant\\Migration\\Mapping\\MappingService\:\:\$languageData type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Mapping/MappingService.php - - message: "#^Property SwagMigrationAssistant\\\\Migration\\\\Mapping\\\\MappingService\\:\\:\\$locales type has no value type specified in iterable type array\\.$#" + message: '#^Property SwagMigrationAssistant\\Migration\\Mapping\\MappingService\:\:\$locales type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Mapping/MappingService.php - - message: "#^Property SwagMigrationAssistant\\\\Migration\\\\Mapping\\\\MappingService\\:\\:\\$mappings type has no value type specified in iterable type array\\.$#" + message: '#^Property SwagMigrationAssistant\\Migration\\Mapping\\MappingService\:\:\$mappings type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Mapping/MappingService.php - - message: "#^Property SwagMigrationAssistant\\\\Migration\\\\Mapping\\\\MappingService\\:\\:\\$migratedSalesChannels type has no value type specified in iterable type array\\.$#" + message: '#^Property SwagMigrationAssistant\\Migration\\Mapping\\MappingService\:\:\$migratedSalesChannels type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Mapping/MappingService.php - - message: "#^Property SwagMigrationAssistant\\\\Migration\\\\Mapping\\\\MappingService\\:\\:\\$writeArray type has no value type specified in iterable type array\\.$#" + message: '#^Property SwagMigrationAssistant\\Migration\\Mapping\\MappingService\:\:\$writeArray type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Mapping/MappingService.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Mapping\\\\MappingServiceInterface\\:\\:getMappings\\(\\) has parameter \\$ids with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Mapping\\MappingServiceInterface\:\:getMappings\(\) has parameter \$ids with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Mapping/MappingServiceInterface.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Mapping\\\\MappingServiceInterface\\:\\:getUuidsByEntity\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Mapping\\MappingServiceInterface\:\:getUuidsByEntity\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Mapping/MappingServiceInterface.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Mapping\\\\MappingServiceInterface\\:\\:preloadMappings\\(\\) has parameter \\$mappingIds with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Mapping\\MappingServiceInterface\:\:preloadMappings\(\) has parameter \$mappingIds with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Mapping/MappingServiceInterface.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Mapping\\\\MappingServiceInterface\\:\\:updateMapping\\(\\) has parameter \\$updateData with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Mapping\\MappingServiceInterface\:\:updateMapping\(\) has parameter \$updateData with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Mapping/MappingServiceInterface.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Mapping\\\\MappingServiceInterface\\:\\:updateMapping\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Mapping\\MappingServiceInterface\:\:updateMapping\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Mapping/MappingServiceInterface.php - - message: "#^Class SwagMigrationAssistant\\\\Migration\\\\Mapping\\\\SwagMigrationMappingCollection extends generic class Shopware\\\\Core\\\\Framework\\\\DataAbstractionLayer\\\\EntityCollection but does not specify its types\\: TElement$#" + message: '#^Class SwagMigrationAssistant\\Migration\\Mapping\\SwagMigrationMappingCollection extends generic class Shopware\\Core\\Framework\\DataAbstractionLayer\\EntityCollection but does not specify its types\: TElement$#' + identifier: missingType.generics count: 1 path: src/Migration/Mapping/SwagMigrationMappingCollection.php - - message: "#^Change \"defineFields\\(\\)\" method visibility to \"protected\" to respect parent method visibility\\.$#" + message: '#^Change "defineFields\(\)" method visibility to "protected" to respect parent method visibility\.$#' + identifier: symplify.parentMethodVisibilityOverride count: 1 path: src/Migration/Mapping/SwagMigrationMappingDefinition.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Media\\\\MediaFileService\\:\\:saveMediaFile\\(\\) has parameter \\$mediaFile with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Media\\MediaFileService\:\:saveMediaFile\(\) has parameter \$mediaFile with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Media/MediaFileService.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Media\\\\MediaFileService\\:\\:saveWrittenFlag\\(\\) has parameter \\$mediaUuids with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Media\\MediaFileService\:\:saveWrittenFlag\(\) has parameter \$mediaUuids with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Media/MediaFileService.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Media\\\\MediaFileService\\:\\:setWrittenFlag\\(\\) has parameter \\$converted with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Media\\MediaFileService\:\:setWrittenFlag\(\) has parameter \$converted with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Media/MediaFileService.php - - message: "#^Property SwagMigrationAssistant\\\\Migration\\\\Media\\\\MediaFileService\\:\\:\\$uuids type has no value type specified in iterable type array\\.$#" + message: '#^Property SwagMigrationAssistant\\Migration\\Media\\MediaFileService\:\:\$uuids type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Media/MediaFileService.php - - message: "#^Property SwagMigrationAssistant\\\\Migration\\\\Media\\\\MediaFileService\\:\\:\\$writeArray type has no value type specified in iterable type array\\.$#" + message: '#^Property SwagMigrationAssistant\\Migration\\Media\\MediaFileService\:\:\$writeArray type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Media/MediaFileService.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Media\\\\MediaFileServiceInterface\\:\\:saveMediaFile\\(\\) has parameter \\$mediaFile with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Media\\MediaFileServiceInterface\:\:saveMediaFile\(\) has parameter \$mediaFile with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Media/MediaFileServiceInterface.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Media\\\\MediaFileServiceInterface\\:\\:setWrittenFlag\\(\\) has parameter \\$converted with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Media\\MediaFileServiceInterface\:\:setWrittenFlag\(\) has parameter \$converted with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Media/MediaFileServiceInterface.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Media\\\\MediaProcessWorkloadStruct\\:\\:__construct\\(\\) has parameter \\$additionalData with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Media\\MediaProcessWorkloadStruct\:\:__construct\(\) has parameter \$additionalData with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Media/MediaProcessWorkloadStruct.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Media\\\\MediaProcessWorkloadStruct\\:\\:getAdditionalData\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Media\\MediaProcessWorkloadStruct\:\:getAdditionalData\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Media/MediaProcessWorkloadStruct.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Media\\\\MediaProcessWorkloadStruct\\:\\:setAdditionalData\\(\\) has parameter \\$additionalData with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Media\\MediaProcessWorkloadStruct\:\:setAdditionalData\(\) has parameter \$additionalData with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Media/MediaProcessWorkloadStruct.php - - message: "#^Property SwagMigrationAssistant\\\\Migration\\\\Media\\\\MediaProcessWorkloadStruct\\:\\:\\$additionalData type has no value type specified in iterable type array\\.$#" + message: '#^Property SwagMigrationAssistant\\Migration\\Media\\MediaProcessWorkloadStruct\:\:\$additionalData type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Media/MediaProcessWorkloadStruct.php - - message: "#^Class SwagMigrationAssistant\\\\Migration\\\\Media\\\\SwagMigrationMediaFileCollection extends generic class Shopware\\\\Core\\\\Framework\\\\DataAbstractionLayer\\\\EntityCollection but does not specify its types\\: TElement$#" + message: '#^Class SwagMigrationAssistant\\Migration\\Media\\SwagMigrationMediaFileCollection extends generic class Shopware\\Core\\Framework\\DataAbstractionLayer\\EntityCollection but does not specify its types\: TElement$#' + identifier: missingType.generics count: 1 path: src/Migration/Media/SwagMigrationMediaFileCollection.php - - message: "#^Change \"defineFields\\(\\)\" method visibility to \"protected\" to respect parent method visibility\\.$#" + message: '#^Change "defineFields\(\)" method visibility to "protected" to respect parent method visibility\.$#' + identifier: symplify.parentMethodVisibilityOverride count: 1 path: src/Migration/Media/SwagMigrationMediaFileDefinition.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\MessageQueue\\\\OrderCountIndexer\\:\\:updateCustomer\\(\\) has parameter \\$ids with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\MessageQueue\\OrderCountIndexer\:\:updateCustomer\(\) has parameter \$ids with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/MessageQueue/OrderCountIndexer.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Run\\\\RunProgress\\:\\:setEntities\\(\\) has parameter \\$entities with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Run\\RunProgress\:\:setEntities\(\) has parameter \$entities with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Run/RunProgress.php - - message: "#^swag_migration_run\\.connection association has a configured autoload\\=\\=\\=true, this is forbidden for platform integrations$#" + message: '#^swag_migration_run\.connection association has a configured autoload\=\=\=true, this is forbidden for platform integrations$#' + identifier: shopware.associationAutoload count: 1 path: src/Migration/Run/SwagMigrationRunDefinition.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Run\\\\SwagMigrationRunEntity\\:\\:getEnvironmentInformation\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Run\\SwagMigrationRunEntity\:\:getEnvironmentInformation\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Run/SwagMigrationRunEntity.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Run\\\\SwagMigrationRunEntity\\:\\:getTotals\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Run\\SwagMigrationRunEntity\:\:getTotals\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Run/SwagMigrationRunEntity.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Run\\\\SwagMigrationRunEntity\\:\\:setEnvironmentInformation\\(\\) has parameter \\$environmentInformation with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Run\\SwagMigrationRunEntity\:\:setEnvironmentInformation\(\) has parameter \$environmentInformation with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Run/SwagMigrationRunEntity.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Run\\\\SwagMigrationRunEntity\\:\\:setTotals\\(\\) has parameter \\$totals with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Run\\SwagMigrationRunEntity\:\:setTotals\(\) has parameter \$totals with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Run/SwagMigrationRunEntity.php - - message: "#^Property SwagMigrationAssistant\\\\Migration\\\\Run\\\\SwagMigrationRunEntity\\:\\:\\$environmentInformation type has no value type specified in iterable type array\\.$#" + message: '#^Property SwagMigrationAssistant\\Migration\\Run\\SwagMigrationRunEntity\:\:\$environmentInformation type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Run/SwagMigrationRunEntity.php - - message: "#^Property SwagMigrationAssistant\\\\Migration\\\\Run\\\\SwagMigrationRunEntity\\:\\:\\$totals type has no value type specified in iterable type array\\.$#" + message: '#^Property SwagMigrationAssistant\\Migration\\Run\\SwagMigrationRunEntity\:\:\$totals type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Run/SwagMigrationRunEntity.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Service\\\\MigrationDataConverter\\:\\:convert\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Service\\MigrationDataConverter\:\:convert\(\) has parameter \$data with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Service/MigrationDataConverter.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Service\\\\MigrationDataConverter\\:\\:convertData\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Service\\MigrationDataConverter\:\:convertData\(\) has parameter \$data with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Service/MigrationDataConverter.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Service\\\\MigrationDataConverter\\:\\:convertData\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Service\\MigrationDataConverter\:\:convertData\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Service/MigrationDataConverter.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Service\\\\MigrationDataConverter\\:\\:filterDeltas\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Service\\MigrationDataConverter\:\:filterDeltas\(\) has parameter \$data with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Service/MigrationDataConverter.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Service\\\\MigrationDataConverterInterface\\:\\:convert\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Service\\MigrationDataConverterInterface\:\:convert\(\) has parameter \$data with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Service/MigrationDataConverterInterface.php - - message: "#^Class SwagMigrationAssistant\\\\Migration\\\\Setting\\\\GeneralSettingCollection extends generic class Shopware\\\\Core\\\\Framework\\\\DataAbstractionLayer\\\\EntityCollection but does not specify its types\\: TElement$#" + message: '#^Class SwagMigrationAssistant\\Migration\\Setting\\GeneralSettingCollection extends generic class Shopware\\Core\\Framework\\DataAbstractionLayer\\EntityCollection but does not specify its types\: TElement$#' + identifier: missingType.generics count: 1 path: src/Migration/Setting/GeneralSettingCollection.php - - message: "#^swag_migration_general_setting\\.selectedConnection association has a configured autoload\\=\\=\\=true, this is forbidden for platform integrations$#" + message: '#^swag_migration_general_setting\.selectedConnection association has a configured autoload\=\=\=true, this is forbidden for platform integrations$#' + identifier: shopware.associationAutoload count: 1 path: src/Migration/Setting/GeneralSettingDefinition.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Writer\\\\TranslationWriter\\:\\:writeData\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Writer\\TranslationWriter\:\:writeData\(\) has parameter \$data with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Writer/TranslationWriter.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Writer\\\\TranslationWriter\\:\\:writeData\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Writer\\TranslationWriter\:\:writeData\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Writer/TranslationWriter.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Writer\\\\WriterInterface\\:\\:writeData\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Writer\\WriterInterface\:\:writeData\(\) has parameter \$data with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Writer/WriterInterface.php - - message: "#^Method SwagMigrationAssistant\\\\Migration\\\\Writer\\\\WriterInterface\\:\\:writeData\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Migration\\Writer\\WriterInterface\:\:writeData\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Migration/Writer/WriterInterface.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Converter\\\\CurrencyConverter\\:\\:getCurrencyTranslation\\(\\) has parameter \\$currency with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Converter\\CurrencyConverter\:\:getCurrencyTranslation\(\) has parameter \$currency with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Converter/CurrencyConverter.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Converter\\\\CurrencyConverter\\:\\:getCurrencyTranslation\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Converter\\CurrencyConverter\:\:getCurrencyTranslation\(\) has parameter \$data with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Converter/CurrencyConverter.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Converter\\\\CustomerGroupConverter\\:\\:getCustomerGroupTranslation\\(\\) has parameter \\$customerGroup with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Converter\\CustomerGroupConverter\:\:getCustomerGroupTranslation\(\) has parameter \$customerGroup with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Converter/CustomerGroupConverter.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Converter\\\\CustomerGroupConverter\\:\\:getCustomerGroupTranslation\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Converter\\CustomerGroupConverter\:\:getCustomerGroupTranslation\(\) has parameter \$data with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Converter/CustomerGroupConverter.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Converter\\\\MediaConverter\\:\\:getMediaTranslation\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Converter\\MediaConverter\:\:getMediaTranslation\(\) has parameter \$data with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Converter/MediaConverter.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Converter\\\\MediaConverter\\:\\:getMediaTranslation\\(\\) has parameter \\$media with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Converter\\MediaConverter\:\:getMediaTranslation\(\) has parameter \$media with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Converter/MediaConverter.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Converter\\\\MediaFolderConverter\\:\\:getConfiguration\\(\\) has parameter \\$setting with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Converter\\MediaFolderConverter\:\:getConfiguration\(\) has parameter \$setting with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Converter/MediaFolderConverter.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Converter\\\\MediaFolderConverter\\:\\:getConfiguration\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Converter\\MediaFolderConverter\:\:getConfiguration\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Converter/MediaFolderConverter.php - - message: "#^Call to an undefined method Shopware\\\\Core\\\\Framework\\\\DataAbstractionLayer\\\\Entity\\:\\:getLanguageId\\(\\)\\.$#" + message: '#^Call to an undefined method Shopware\\Core\\Framework\\DataAbstractionLayer\\Entity\:\:getLanguageId\(\)\.$#' + identifier: method.notFound count: 1 path: src/Profile/Shopware/Converter/SalesChannelConverter.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Converter\\\\SalesChannelConverter\\:\\:__construct\\(\\) has parameter \\$languagePackRepo with generic class Shopware\\\\Core\\\\Framework\\\\DataAbstractionLayer\\\\EntityRepository but does not specify its types\\: TEntityCollection$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Converter\\SalesChannelConverter\:\:__construct\(\) has parameter \$languagePackRepo with generic class Shopware\\Core\\Framework\\DataAbstractionLayer\\EntityRepository but does not specify its types\: TEntityCollection$#' + identifier: missingType.generics count: 1 path: src/Profile/Shopware/Converter/SalesChannelConverter.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Api\\\\Reader\\\\TableCountReader\\:\\:logExceptions\\(\\) has parameter \\$exceptionArray with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Api\\Reader\\TableCountReader\:\:logExceptions\(\) has parameter \$exceptionArray with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Api/Reader/TableCountReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Api\\\\Reader\\\\TableCountReader\\:\\:prepareTotals\\(\\) has parameter \\$result with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Api\\Reader\\TableCountReader\:\:prepareTotals\(\) has parameter \$result with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Api/Reader/TableCountReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Api\\\\Reader\\\\TableCountReader\\:\\:readTotals\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Api\\Reader\\TableCountReader\:\:readTotals\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Api/Reader/TableCountReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Api\\\\Reader\\\\TableReader\\:\\:read\\(\\) has parameter \\$filter with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Api\\Reader\\TableReader\:\:read\(\) has parameter \$filter with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Api/Reader/TableReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Api\\\\Reader\\\\TableReader\\:\\:read\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Api\\Reader\\TableReader\:\:read\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Api/Reader/TableReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Api\\\\ShopwareApiGateway\\:\\:readTable\\(\\) has parameter \\$filter with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Api\\ShopwareApiGateway\:\:readTable\(\) has parameter \$filter with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Api/ShopwareApiGateway.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Api\\\\ShopwareApiGateway\\:\\:readTable\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Api\\ShopwareApiGateway\:\:readTable\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Api/ShopwareApiGateway.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\CategoryReader\\:\\:fetchData\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\CategoryReader\:\:fetchData\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/CategoryReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\CategoryReader\\:\\:fetchMainCategoryLocales\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\CategoryReader\:\:fetchMainCategoryLocales\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/CategoryReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\CategoryReader\\:\\:generateAllLocales\\(\\) has parameter \\$categories with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\CategoryReader\:\:generateAllLocales\(\) has parameter \$categories with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/CategoryReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\CategoryReader\\:\\:generateAllLocales\\(\\) has parameter \\$mainCategoryLocales with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\CategoryReader\:\:generateAllLocales\(\) has parameter \$mainCategoryLocales with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/CategoryReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\CategoryReader\\:\\:generateAllLocales\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\CategoryReader\:\:generateAllLocales\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/CategoryReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\CategoryReader\\:\\:getIgnoredCategories\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\CategoryReader\:\:getIgnoredCategories\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/CategoryReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\CrossSellingReader\\:\\:enrichWithPositionData\\(\\) has parameter \\$fetchedCrossSelling with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\CrossSellingReader\:\:enrichWithPositionData\(\) has parameter \$fetchedCrossSelling with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/CrossSellingReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\CrossSellingReader\\:\\:fetchData\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\CrossSellingReader\:\:fetchData\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/CrossSellingReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\CurrencyReader\\:\\:fetchData\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\CurrencyReader\:\:fetchData\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/CurrencyReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\CustomerGroupReader\\:\\:fetchCustomerGroupDiscounts\\(\\) has parameter \\$groupIds with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\CustomerGroupReader\:\:fetchCustomerGroupDiscounts\(\) has parameter \$groupIds with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/CustomerGroupReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\CustomerGroupReader\\:\\:fetchCustomerGroupDiscounts\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\CustomerGroupReader\:\:fetchCustomerGroupDiscounts\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/CustomerGroupReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\CustomerGroupReader\\:\\:fetchCustomerGroups\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\CustomerGroupReader\:\:fetchCustomerGroups\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/CustomerGroupReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\LanguageReader\\:\\:appendAssociatedData\\(\\) has parameter \\$locales with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\LanguageReader\:\:appendAssociatedData\(\) has parameter \$locales with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/LanguageReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\LanguageReader\\:\\:appendAssociatedData\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\LanguageReader\:\:appendAssociatedData\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/LanguageReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\LanguageReader\\:\\:fetchLocales\\(\\) has parameter \\$fetchedShopLocaleIds with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\LanguageReader\:\:fetchLocales\(\) has parameter \$fetchedShopLocaleIds with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/LanguageReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\LanguageReader\\:\\:fetchLocales\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\LanguageReader\:\:fetchLocales\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/LanguageReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\LanguageReader\\:\\:fetchShopLocaleIds\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\LanguageReader\:\:fetchShopLocaleIds\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/LanguageReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\LanguageReader\\:\\:fetchTranslations\\(\\) has parameter \\$locales with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\LanguageReader\:\:fetchTranslations\(\) has parameter \$locales with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/LanguageReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\LanguageReader\\:\\:fetchTranslations\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\LanguageReader\:\:fetchTranslations\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/LanguageReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\MainVariantRelationReader\\:\\:fetchMainVariantRelations\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\MainVariantRelationReader\:\:fetchMainVariantRelations\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/MainVariantRelationReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\MediaAlbumReader\\:\\:fetchAlbums\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\MediaAlbumReader\:\:fetchAlbums\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/MediaAlbumReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\MediaAlbumReader\\:\\:getChildAlbums\\(\\) has parameter \\$mediaAlbums with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\MediaAlbumReader\:\:getChildAlbums\(\) has parameter \$mediaAlbums with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/MediaAlbumReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\MediaAlbumReader\\:\\:getChildAlbums\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\MediaAlbumReader\:\:getChildAlbums\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/MediaAlbumReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\MediaAlbumReader\\:\\:prepareMediaAlbums\\(\\) has parameter \\$mediaAlbums with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\MediaAlbumReader\:\:prepareMediaAlbums\(\) has parameter \$mediaAlbums with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/MediaAlbumReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\MediaAlbumReader\\:\\:prepareMediaAlbums\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\MediaAlbumReader\:\:prepareMediaAlbums\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/MediaAlbumReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\MediaReader\\:\\:fetchData\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\MediaReader\:\:fetchData\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/MediaReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\MediaReader\\:\\:prepareMedia\\(\\) has parameter \\$media with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\MediaReader\:\:prepareMedia\(\) has parameter \$media with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/MediaReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\MediaReader\\:\\:prepareMedia\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\MediaReader\:\:prepareMedia\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/MediaReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\NewsletterRecipientReader\\:\\:addShopAndLocaleByCustomer\\(\\) has parameter \\$item with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\NewsletterRecipientReader\:\:addShopAndLocaleByCustomer\(\) has parameter \$item with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/NewsletterRecipientReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\NewsletterRecipientReader\\:\\:addShopAndLocaleByCustomer\\(\\) has parameter \\$shop with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\NewsletterRecipientReader\:\:addShopAndLocaleByCustomer\(\) has parameter \$shop with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/NewsletterRecipientReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\NewsletterRecipientReader\\:\\:addShopAndLocaleByGroupId\\(\\) has parameter \\$defaultShop with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\NewsletterRecipientReader\:\:addShopAndLocaleByGroupId\(\) has parameter \$defaultShop with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/NewsletterRecipientReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\NewsletterRecipientReader\\:\\:addShopAndLocaleByGroupId\\(\\) has parameter \\$item with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\NewsletterRecipientReader\:\:addShopAndLocaleByGroupId\(\) has parameter \$item with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/NewsletterRecipientReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\NewsletterRecipientReader\\:\\:addShopAndLocaleByGroupId\\(\\) has parameter \\$shops with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\NewsletterRecipientReader\:\:addShopAndLocaleByGroupId\(\) has parameter \$shops with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/NewsletterRecipientReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\NewsletterRecipientReader\\:\\:fetchData\\(\\) has parameter \\$ids with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\NewsletterRecipientReader\:\:fetchData\(\) has parameter \$ids with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/NewsletterRecipientReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\NewsletterRecipientReader\\:\\:fetchData\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\NewsletterRecipientReader\:\:fetchData\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/NewsletterRecipientReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\NewsletterRecipientReader\\:\\:getDefaultShopAndLocaleByGroupId\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\NewsletterRecipientReader\:\:getDefaultShopAndLocaleByGroupId\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/NewsletterRecipientReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\NewsletterRecipientReader\\:\\:getGroupedResult\\(\\) has parameter \\$shops with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\NewsletterRecipientReader\:\:getGroupedResult\(\) has parameter \$shops with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/NewsletterRecipientReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\NewsletterRecipientReader\\:\\:getGroupedResult\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\NewsletterRecipientReader\:\:getGroupedResult\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/NewsletterRecipientReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\NewsletterRecipientReader\\:\\:getShopsAndLocalesByCustomer\\(\\) has parameter \\$ids with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\NewsletterRecipientReader\:\:getShopsAndLocalesByCustomer\(\) has parameter \$ids with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/NewsletterRecipientReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\NewsletterRecipientReader\\:\\:getShopsAndLocalesByCustomer\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\NewsletterRecipientReader\:\:getShopsAndLocalesByCustomer\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/NewsletterRecipientReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\NewsletterRecipientReader\\:\\:getShopsAndLocalesByGroupId\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\NewsletterRecipientReader\:\:getShopsAndLocalesByGroupId\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/NewsletterRecipientReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\OrderDocumentReader\\:\\:fetchDocuments\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\OrderDocumentReader\:\:fetchDocuments\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/OrderDocumentReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\ProductOptionRelationReader\\:\\:fetchData\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\ProductOptionRelationReader\:\:fetchData\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/ProductOptionRelationReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\ProductPropertyRelationReader\\:\\:fetchData\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\ProductPropertyRelationReader\:\:fetchData\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/ProductPropertyRelationReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\ProductReviewReader\\:\\:fetchReviews\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\ProductReviewReader\:\:fetchReviews\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/ProductReviewReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\PromotionReader\\:\\:fetchIndividualCodes\\(\\) has parameter \\$ids with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\PromotionReader\:\:fetchIndividualCodes\(\) has parameter \$ids with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/PromotionReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\PromotionReader\\:\\:fetchIndividualCodes\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\PromotionReader\:\:fetchIndividualCodes\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/PromotionReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\PromotionReader\\:\\:fetchPromotions\\(\\) has parameter \\$ids with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\PromotionReader\:\:fetchPromotions\(\) has parameter \$ids with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/PromotionReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\PromotionReader\\:\\:fetchPromotions\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\PromotionReader\:\:fetchPromotions\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/PromotionReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\PropertyGroupOptionReader\\:\\:fetchData\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\PropertyGroupOptionReader\:\:fetchData\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/PropertyGroupOptionReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\ShippingMethodReader\\:\\:fetchExcludedCategories\\(\\) has parameter \\$shippingMethodIds with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\ShippingMethodReader\:\:fetchExcludedCategories\(\) has parameter \$shippingMethodIds with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/ShippingMethodReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\ShippingMethodReader\\:\\:fetchExcludedCategories\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\ShippingMethodReader\:\:fetchExcludedCategories\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/ShippingMethodReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\ShippingMethodReader\\:\\:fetchPaymentMethods\\(\\) has parameter \\$shippingMethodIds with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\ShippingMethodReader\:\:fetchPaymentMethods\(\) has parameter \$shippingMethodIds with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/ShippingMethodReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\ShippingMethodReader\\:\\:fetchPaymentMethods\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\ShippingMethodReader\:\:fetchPaymentMethods\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/ShippingMethodReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\ShippingMethodReader\\:\\:fetchShippingCosts\\(\\) has parameter \\$shippingMethodIds with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\ShippingMethodReader\:\:fetchShippingCosts\(\) has parameter \$shippingMethodIds with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/ShippingMethodReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\ShippingMethodReader\\:\\:fetchShippingCosts\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\ShippingMethodReader\:\:fetchShippingCosts\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/ShippingMethodReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\ShippingMethodReader\\:\\:fetchShippingCountries\\(\\) has parameter \\$shippingMethodIds with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\ShippingMethodReader\:\:fetchShippingCountries\(\) has parameter \$shippingMethodIds with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/ShippingMethodReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\ShippingMethodReader\\:\\:fetchShippingCountries\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\ShippingMethodReader\:\:fetchShippingCountries\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/ShippingMethodReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\ShippingMethodReader\\:\\:fetchShippingMethods\\(\\) has parameter \\$shippingMethodIds with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\ShippingMethodReader\:\:fetchShippingMethods\(\) has parameter \$shippingMethodIds with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/ShippingMethodReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\ShippingMethodReader\\:\\:fetchShippingMethods\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\ShippingMethodReader\:\:fetchShippingMethods\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/ShippingMethodReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\TableReader\\:\\:read\\(\\) has parameter \\$filter with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\TableReader\:\:read\(\) has parameter \$filter with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/TableReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\TableReader\\:\\:read\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\TableReader\:\:read\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/TableReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\Reader\\\\TranslationReader\\:\\:fetchTranslations\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\Reader\\TranslationReader\:\:fetchTranslations\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/Reader/TranslationReader.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\ShopwareLocalGateway\\:\\:readTable\\(\\) has parameter \\$filter with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\ShopwareLocalGateway\:\:readTable\(\) has parameter \$filter with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/ShopwareLocalGateway.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\Local\\\\ShopwareLocalGateway\\:\\:readTable\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\Local\\ShopwareLocalGateway\:\:readTable\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/Local/ShopwareLocalGateway.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\ShopwareGatewayInterface\\:\\:readTable\\(\\) has parameter \\$filter with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\ShopwareGatewayInterface\:\:readTable\(\) has parameter \$filter with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/ShopwareGatewayInterface.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\ShopwareGatewayInterface\\:\\:readTable\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\ShopwareGatewayInterface\:\:readTable\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/ShopwareGatewayInterface.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\TableCountReaderInterface\\:\\:readTotals\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\TableCountReaderInterface\:\:readTotals\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/TableCountReaderInterface.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\TableReaderInterface\\:\\:read\\(\\) has parameter \\$filter with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\TableReaderInterface\:\:read\(\) has parameter \$filter with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/TableReaderInterface.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Gateway\\\\TableReaderInterface\\:\\:read\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Gateway\\TableReaderInterface\:\:read\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Gateway/TableReaderInterface.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Media\\\\LocalOrderDocumentProcessor\\:\\:copyMediaFiles\\(\\) has parameter \\$media with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Media\\LocalOrderDocumentProcessor\:\:copyMediaFiles\(\) has parameter \$media with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Media/LocalOrderDocumentProcessor.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Media\\\\LocalOrderDocumentProcessor\\:\\:persistFileToMedia\\(\\) has parameter \\$media with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Media\\LocalOrderDocumentProcessor\:\:persistFileToMedia\(\) has parameter \$media with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Media/LocalOrderDocumentProcessor.php - - message: "#^Parameter \\#1 \\$blob of method Shopware\\\\Core\\\\Content\\\\Media\\\\MediaService\\:\\:saveFile\\(\\) expects string, string\\|false given\\.$#" + message: '#^Parameter \#1 \$blob of method Shopware\\Core\\Content\\Media\\MediaService\:\:saveFile\(\) expects string, string\|false given\.$#' + identifier: argument.type count: 3 path: src/Profile/Shopware/Media/LocalOrderDocumentProcessor.php - - message: "#^Parameter \\#3 \\$contentType of method Shopware\\\\Core\\\\Content\\\\Media\\\\MediaService\\:\\:saveFile\\(\\) expects string, string\\|false given\\.$#" + message: '#^Parameter \#3 \$contentType of method Shopware\\Core\\Content\\Media\\MediaService\:\:saveFile\(\) expects string, string\|false given\.$#' + identifier: argument.type count: 3 path: src/Profile/Shopware/Media/LocalOrderDocumentProcessor.php - - message: "#^Parameter \\#4 \\$filename of method Shopware\\\\Core\\\\Content\\\\Media\\\\MediaService\\:\\:saveFile\\(\\) expects string, string\\|null given\\.$#" + message: '#^Parameter \#4 \$filename of method Shopware\\Core\\Content\\Media\\MediaService\:\:saveFile\(\) expects string, string\|null given\.$#' + identifier: argument.type count: 1 path: src/Profile/Shopware/Media/LocalOrderDocumentProcessor.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Media\\\\LocalProductDownloadProcessor\\:\\:copyMediaFiles\\(\\) has parameter \\$media with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Media\\LocalProductDownloadProcessor\:\:copyMediaFiles\(\) has parameter \$media with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Media/LocalProductDownloadProcessor.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware\\\\Media\\\\LocalProductDownloadProcessor\\:\\:persistFileToMedia\\(\\) has parameter \\$media with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware\\Media\\LocalProductDownloadProcessor\:\:persistFileToMedia\(\) has parameter \$media with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware/Media/LocalProductDownloadProcessor.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware6\\\\Converter\\\\CmsPageConverter\\:\\:processSubentities\\(\\) has parameter \\$sections with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware6\\Converter\\CmsPageConverter\:\:processSubentities\(\) has parameter \$sections with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware6/Converter/CmsPageConverter.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware6\\\\Converter\\\\CmsPageConverter\\:\\:updateTranslations\\(\\) has parameter \\$converted with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware6\\Converter\\CmsPageConverter\:\:updateTranslations\(\) has parameter \$converted with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware6/Converter/CmsPageConverter.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware6\\\\Converter\\\\NumberRangeConverter\\:\\:checkForExistingNumberRange\\(\\) has parameter \\$converted with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware6\\Converter\\NumberRangeConverter\:\:checkForExistingNumberRange\(\) has parameter \$converted with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware6/Converter/NumberRangeConverter.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware6\\\\Converter\\\\ProductConverter\\:\\:checkDefaultCurrency\\(\\) has parameter \\$source with no value type specified in iterable type array\\.$#" - count: 1 - path: src/Profile/Shopware6/Converter/ProductConverter.php - - - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware6\\\\Converter\\\\PropertyGroupConverter\\:\\:convertOption\\(\\) has parameter \\$option with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware6\\Converter\\PropertyGroupConverter\:\:convertOption\(\) has parameter \$option with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware6/Converter/PropertyGroupConverter.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware6\\\\Converter\\\\RuleConverter\\:\\:recursiveAddChildren\\(\\) has parameter \\$parentMap with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware6\\Converter\\RuleConverter\:\:recursiveAddChildren\(\) has parameter \$parentMap with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware6/Converter/RuleConverter.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware6\\\\Converter\\\\RuleConverter\\:\\:recursiveAddChildren\\(\\) has parameter \\$sorted with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware6\\Converter\\RuleConverter\:\:recursiveAddChildren\(\) has parameter \$sorted with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware6/Converter/RuleConverter.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware6\\\\Converter\\\\RuleConverter\\:\\:sortConditions\\(\\) has parameter \\$conditions with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware6\\Converter\\RuleConverter\:\:sortConditions\(\) has parameter \$conditions with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware6/Converter/RuleConverter.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware6\\\\Converter\\\\RuleConverter\\:\\:sortConditions\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware6\\Converter\\RuleConverter\:\:sortConditions\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware6/Converter/RuleConverter.php - - message: "#^Method SwagMigrationAssistant\\\\Profile\\\\Shopware6\\\\Converter\\\\ShopwareMediaConverter\\:\\:updateMediaAssociation\\(\\) has parameter \\$mediaArray with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Profile\\Shopware6\\Converter\\ShopwareMediaConverter\:\:updateMediaAssociation\(\) has parameter \$mediaArray with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/Profile/Shopware6/Converter/ShopwareMediaConverter.php - - message: "#^Method SwagMigrationAssistant\\\\Test\\\\DataProvider\\\\Service\\\\EnvironmentServiceTest\\:\\:provideEnvironments\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Test\\DataProvider\\Service\\EnvironmentServiceTest\:\:provideEnvironments\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: tests/DataProvider/Service/EnvironmentServiceTest.php - - message: "#^Property SwagMigrationAssistant\\\\Test\\\\DeprecatedTagTest\\:\\:\\$whiteList type has no value type specified in iterable type array\\.$#" + message: '#^Property SwagMigrationAssistant\\Test\\DeprecatedTagTest\:\:\$whiteList type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: tests/DeprecatedTagTest.php - - message: "#^Method SwagMigrationAssistant\\\\Test\\\\Migration\\\\Converter\\\\ConverterRegistryTest\\:\\:converterProvider\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Test\\Migration\\Converter\\ConverterRegistryTest\:\:converterProvider\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: tests/Migration/Converter/ConverterRegistryTest.php - - message: "#^Call to deprecated method getMockForAbstractClass\\(\\) of class PHPUnit\\\\Framework\\\\TestCase\\.$#" + message: '#^Call to deprecated method getMockForAbstractClass\(\) of class PHPUnit\\Framework\\TestCase\.$#' + identifier: method.deprecated count: 1 path: tests/Migration/Writer/AbstractWriterTest.php - - message: "#^Property SwagMigrationAssistant\\\\Test\\\\Migration\\\\Writer\\\\AbstractWriterTest\\:\\:\\$dataToWrite type has no value type specified in iterable type array\\.$#" + message: '#^Property SwagMigrationAssistant\\Test\\Migration\\Writer\\AbstractWriterTest\:\:\$dataToWrite type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: tests/Migration/Writer/AbstractWriterTest.php - - message: "#^Property SwagMigrationAssistant\\\\Test\\\\Migration\\\\Writer\\\\AbstractWriterTest\\:\\:\\$writeResult type has no value type specified in iterable type array\\.$#" + message: '#^Property SwagMigrationAssistant\\Test\\Migration\\Writer\\AbstractWriterTest\:\:\$writeResult type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: tests/Migration/Writer/AbstractWriterTest.php - - message: "#^Class SwagMigrationAssistant\\\\Test\\\\Mock\\\\DummyCollection implements generic interface IteratorAggregate but does not specify its types\\: TKey, TValue$#" + message: '#^Class SwagMigrationAssistant\\Test\\Mock\\DummyCollection implements generic interface IteratorAggregate but does not specify its types\: TKey, TValue$#' + identifier: missingType.generics count: 1 path: tests/Mock/DummyCollection.php - - message: "#^Method SwagMigrationAssistant\\\\Test\\\\Mock\\\\DummyCollection\\:\\:__construct\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Test\\Mock\\DummyCollection\:\:__construct\(\) has parameter \$data with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: tests/Mock/DummyCollection.php - - message: "#^Method SwagMigrationAssistant\\\\Test\\\\Mock\\\\DummyCollection\\:\\:getIterator\\(\\) return type with generic class ArrayIterator does not specify its types\\: TKey, TValue$#" + message: '#^Method SwagMigrationAssistant\\Test\\Mock\\DummyCollection\:\:getIterator\(\) return type with generic class ArrayIterator does not specify its types\: TKey, TValue$#' + identifier: missingType.generics count: 1 path: tests/Mock/DummyCollection.php - - message: "#^Method SwagMigrationAssistant\\\\Test\\\\Mock\\\\Gateway\\\\Dummy\\\\Api\\\\Reader\\\\ApiDummyReader\\:\\:read\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Test\\Mock\\Gateway\\Dummy\\Api\\Reader\\ApiDummyReader\:\:read\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: tests/Mock/Gateway/Dummy/Api/Reader/ApiDummyReader.php - - message: "#^Method SwagMigrationAssistant\\\\Test\\\\Mock\\\\Gateway\\\\Dummy\\\\Api\\\\Reader\\\\EnvironmentDummyReader\\:\\:read\\(\\) has parameter \\$params with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Test\\Mock\\Gateway\\Dummy\\Api\\Reader\\EnvironmentDummyReader\:\:read\(\) has parameter \$params with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: tests/Mock/Gateway/Dummy/Api/Reader/EnvironmentDummyReader.php - - message: "#^Method SwagMigrationAssistant\\\\Test\\\\Mock\\\\Gateway\\\\Dummy\\\\Api\\\\Reader\\\\TableCountDummyReader\\:\\:readTotals\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Test\\Mock\\Gateway\\Dummy\\Api\\Reader\\TableCountDummyReader\:\:readTotals\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: tests/Mock/Gateway/Dummy/Api/Reader/TableCountDummyReader.php - - message: "#^Method SwagMigrationAssistant\\\\Test\\\\Mock\\\\Migration\\\\Logging\\\\DummyLoggingService\\:\\:getLoggingArray\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Test\\Mock\\Migration\\Logging\\DummyLoggingService\:\:getLoggingArray\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: tests/Mock/Migration/Logging/DummyLoggingService.php - - message: "#^Method SwagMigrationAssistant\\\\Test\\\\Mock\\\\Migration\\\\Mapping\\\\Dummy6MappingService\\:\\:createListItemMapping\\(\\) has parameter \\$additionalData with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Test\\Mock\\Migration\\Mapping\\Dummy6MappingService\:\:createListItemMapping\(\) has parameter \$additionalData with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: tests/Mock/Migration/Mapping/Dummy6MappingService.php - - message: "#^Method SwagMigrationAssistant\\\\Test\\\\Mock\\\\Migration\\\\Mapping\\\\Dummy6MappingService\\:\\:getMappings\\(\\) has parameter \\$ids with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Test\\Mock\\Migration\\Mapping\\Dummy6MappingService\:\:getMappings\(\) has parameter \$ids with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: tests/Mock/Migration/Mapping/Dummy6MappingService.php - - message: "#^Method SwagMigrationAssistant\\\\Test\\\\Mock\\\\Migration\\\\Mapping\\\\Dummy6MappingService\\:\\:getUuidList\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Test\\Mock\\Migration\\Mapping\\Dummy6MappingService\:\:getUuidList\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: tests/Mock/Migration/Mapping/Dummy6MappingService.php - - message: "#^Method SwagMigrationAssistant\\\\Test\\\\Mock\\\\Migration\\\\Mapping\\\\Dummy6MappingService\\:\\:getUuidsByEntity\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Test\\Mock\\Migration\\Mapping\\Dummy6MappingService\:\:getUuidsByEntity\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: tests/Mock/Migration/Mapping/Dummy6MappingService.php - - message: "#^Method SwagMigrationAssistant\\\\Test\\\\Mock\\\\Migration\\\\Mapping\\\\Dummy6MappingService\\:\\:preloadMappings\\(\\) has parameter \\$mappingIds with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Test\\Mock\\Migration\\Mapping\\Dummy6MappingService\:\:preloadMappings\(\) has parameter \$mappingIds with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: tests/Mock/Migration/Mapping/Dummy6MappingService.php - - message: "#^Method SwagMigrationAssistant\\\\Test\\\\Mock\\\\Migration\\\\Mapping\\\\DummyMappingService\\:\\:createListItemMapping\\(\\) has parameter \\$additionalData with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Test\\Mock\\Migration\\Mapping\\DummyMappingService\:\:createListItemMapping\(\) has parameter \$additionalData with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: tests/Mock/Migration/Mapping/DummyMappingService.php - - message: "#^Method SwagMigrationAssistant\\\\Test\\\\Mock\\\\Migration\\\\Mapping\\\\DummyMappingService\\:\\:getMappingArray\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Test\\Mock\\Migration\\Mapping\\DummyMappingService\:\:getMappingArray\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: tests/Mock/Migration/Mapping/DummyMappingService.php - - message: "#^Method SwagMigrationAssistant\\\\Test\\\\Mock\\\\Migration\\\\Mapping\\\\DummyMappingService\\:\\:getMappings\\(\\) has parameter \\$ids with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Test\\Mock\\Migration\\Mapping\\DummyMappingService\:\:getMappings\(\) has parameter \$ids with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: tests/Mock/Migration/Mapping/DummyMappingService.php - - message: "#^Method SwagMigrationAssistant\\\\Test\\\\Mock\\\\Migration\\\\Mapping\\\\DummyMappingService\\:\\:getUuidList\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Test\\Mock\\Migration\\Mapping\\DummyMappingService\:\:getUuidList\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: tests/Mock/Migration/Mapping/DummyMappingService.php - - message: "#^Method SwagMigrationAssistant\\\\Test\\\\Mock\\\\Migration\\\\Mapping\\\\DummyMappingService\\:\\:getUuidsByEntity\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Test\\Mock\\Migration\\Mapping\\DummyMappingService\:\:getUuidsByEntity\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: tests/Mock/Migration/Mapping/DummyMappingService.php - - message: "#^Method SwagMigrationAssistant\\\\Test\\\\Mock\\\\Migration\\\\Mapping\\\\DummyMappingService\\:\\:saveMapping\\(\\) has parameter \\$mapping with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Test\\Mock\\Migration\\Mapping\\DummyMappingService\:\:saveMapping\(\) has parameter \$mapping with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: tests/Mock/Migration/Mapping/DummyMappingService.php - - message: "#^Method SwagMigrationAssistant\\\\Test\\\\Mock\\\\Migration\\\\Media\\\\DummyMediaFileService\\:\\:getMediaFileArray\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Test\\Mock\\Migration\\Media\\DummyMediaFileService\:\:getMediaFileArray\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: tests/Mock/Migration/Media/DummyMediaFileService.php - - message: "#^Method SwagMigrationAssistant\\\\Test\\\\Mock\\\\Migration\\\\Media\\\\DummyMediaFileService\\:\\:setWrittenFlag\\(\\) has parameter \\$converted with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Test\\Mock\\Migration\\Media\\DummyMediaFileService\:\:setWrittenFlag\(\) has parameter \$converted with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: tests/Mock/Migration/Media/DummyMediaFileService.php - - message: "#^Method SwagMigrationAssistant\\\\Test\\\\Mock\\\\Migration\\\\Writer\\\\DummyWriter\\:\\:writeData\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Test\\Mock\\Migration\\Writer\\DummyWriter\:\:writeData\(\) has parameter \$data with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: tests/Mock/Migration/Writer/DummyWriter.php - - message: "#^Method SwagMigrationAssistant\\\\Test\\\\Mock\\\\Migration\\\\Writer\\\\DummyWriter\\:\\:writeData\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Test\\Mock\\Migration\\Writer\\DummyWriter\:\:writeData\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: tests/Mock/Migration/Writer/DummyWriter.php - - message: "#^Parameter \\#3 \\$body of class GuzzleHttp\\\\Psr7\\\\Response constructor expects Psr\\\\Http\\\\Message\\\\StreamInterface\\|resource\\|string\\|null, string\\|false given\\.$#" + message: '#^Parameter \#3 \$body of class GuzzleHttp\\Psr7\\Response constructor expects Psr\\Http\\Message\\StreamInterface\|resource\|string\|null, string\|false given\.$#' + identifier: argument.type count: 1 path: tests/Profile/Shopware/Gateway/ApiReaderTest.php - - message: "#^Method SwagMigrationAssistant\\\\Test\\\\Profile\\\\Shopware\\\\Gateway\\\\LocalGatewayTest\\:\\:profileProvider\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Test\\Profile\\Shopware\\Gateway\\LocalGatewayTest\:\:profileProvider\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: tests/Profile/Shopware/Gateway/LocalGatewayTest.php - - message: "#^Method SwagMigrationAssistant\\\\Test\\\\Profile\\\\Shopware6\\\\Converter\\\\ProductSortingConverterTest\\:\\:loadMapping\\(\\) has parameter \\$mappingArray with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Test\\Profile\\Shopware6\\Converter\\ProductSortingConverterTest\:\:loadMapping\(\) has parameter \$mappingArray with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: tests/Profile/Shopware6/Converter/ProductSortingConverterTest.php - - message: "#^Method SwagMigrationAssistant\\\\Test\\\\Profile\\\\Shopware6\\\\Converter\\\\ShopwareConverterTest\\:\\:dataProviderConvert\\(\\) return type has no value type specified in iterable type iterable\\.$#" + message: '#^Method SwagMigrationAssistant\\Test\\Profile\\Shopware6\\Converter\\ShopwareConverterTest\:\:dataProviderConvert\(\) return type has no value type specified in iterable type iterable\.$#' + identifier: missingType.iterableValue count: 1 path: tests/Profile/Shopware6/Converter/ShopwareConverterTest.php - - message: "#^Method SwagMigrationAssistant\\\\Test\\\\Profile\\\\Shopware6\\\\Converter\\\\ShopwareConverterTest\\:\\:loadMapping\\(\\) has parameter \\$mappingArray with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Test\\Profile\\Shopware6\\Converter\\ShopwareConverterTest\:\:loadMapping\(\) has parameter \$mappingArray with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: tests/Profile/Shopware6/Converter/ShopwareConverterTest.php - - message: "#^Method SwagMigrationAssistant\\\\Test\\\\Profile\\\\Shopware6\\\\Gateway\\\\Connection\\\\ConnectionFactoryTests\\:\\:testCreateApiClient\\(\\) has parameter \\$credentials with no value type specified in iterable type array\\.$#" + message: '#^Method SwagMigrationAssistant\\Test\\Profile\\Shopware6\\Gateway\\Connection\\ConnectionFactoryTests\:\:testCreateApiClient\(\) has parameter \$credentials with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: tests/Profile/Shopware6/Gateway/Connection/ConnectionFactoryTests.php diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 6eba93c02..f236d3685 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -18,27 +18,13 @@ parameters: consoleApplicationLoader: %ShopwareRoot%/src/Core/DevOps/StaticAnalyze/console-application.php type_perfect: narrow_return: true - narrow_param: true + narrow_param: false ignoreErrors: - message: '#Service ".*" is private#' paths: - tests/**/*Test.php - - # Ignore hash functions rule for the following files because we use it in another context - message: '#Do not use .* function, use class Shopware\\Core\\Framework\\Util\\Hasher instead#' - paths: - - src/Migration/Media/Processor/HttpDownloadServiceBase.php - - src/Migration/Service/MigrationDataConverter.php - - src/Profile/Shopware/Converter/OrderConverter.php - - src/Profile/Shopware/Converter/ProductConverter.php - - src/Profile/Shopware/Converter/ProductOptionRelationConverter.php - - src/Profile/Shopware/Converter/ProductPropertyRelationConverter.php - - src/Profile/Shopware/Converter/PropertyGroupOptionConverter.php - - src/Profile/Shopware/Converter/ShippingMethodConverter.php - - src/Profile/Shopware/Media/Strategy/Md5StrategyResolver.php - - src/Migration/Converter/Converter.php - - # To fix those issues, the AbstractProvider needs a generic type, which could then be used further down in the methods as typehints for other generic typed parameters message: '#(readTotalFromRepo|readTableFromRepo|cleanupSearchResult)\(\) has parameter .* with generic class#' path: src/DataProvider/Provider/Data/AbstractProvider.php diff --git a/src/Command/AbortMigrationCommand.php b/src/Command/AbortMigrationCommand.php deleted file mode 100644 index 6b4619b0a..000000000 --- a/src/Command/AbortMigrationCommand.php +++ /dev/null @@ -1,49 +0,0 @@ - - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace SwagMigrationAssistant\Command; - -use Shopware\Core\Framework\Context; -use Shopware\Core\Framework\Log\Package; -use SwagMigrationAssistant\Exception\NoRunningMigrationException; -use SwagMigrationAssistant\Migration\Run\RunServiceInterface; -use Symfony\Component\Console\Attribute\AsCommand; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -#[Package('fundamentals@after-sales')] -#[AsCommand( - name: 'migration:abort', - description: 'Abort the current migration', -)] -class AbortMigrationCommand extends Command -{ - public function __construct( - private readonly RunServiceInterface $runService, - ?string $name = null, - ) { - parent::__construct($name); - } - - protected function execute(InputInterface $input, OutputInterface $output): int - { - $context = Context::createCLIContext(); - - try { - $this->runService->abortMigration($context); - } catch (NoRunningMigrationException $exception) { - $output->writeln('Currently there is no migration running.'); - - return Command::FAILURE; - } - - $output->writeln('The migration is aborted.'); - - return Command::SUCCESS; - } -} diff --git a/src/Command/GetMigrationProgressCommand.php b/src/Command/GetMigrationProgressCommand.php deleted file mode 100644 index 22d0a8ce5..000000000 --- a/src/Command/GetMigrationProgressCommand.php +++ /dev/null @@ -1,91 +0,0 @@ - - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace SwagMigrationAssistant\Command; - -use Shopware\Core\Framework\Context; -use Shopware\Core\Framework\Log\Package; -use SwagMigrationAssistant\Migration\Run\MigrationStep; -use SwagMigrationAssistant\Migration\Run\RunServiceInterface; -use Symfony\Component\Console\Attribute\AsCommand; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Helper\ProgressBar; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Output\OutputInterface; - -#[Package('fundamentals@after-sales')] -#[AsCommand( - name: 'migration:get-progress', - description: 'Shows the current progress of a migration', -)] -class GetMigrationProgressCommand extends Command -{ - private const PROGRESSBAR_FORMAT = '[%bar%] %current%/%max% '; - - public function __construct( - private readonly RunServiceInterface $runService, - ?string $name = null, - ) { - parent::__construct($name); - } - - protected function configure(): void - { - $this->addOption('refreshRate', 'r', InputOption::VALUE_OPTIONAL, 'Refresh rate in milliseconds', 500); - } - - protected function execute(InputInterface $input, OutputInterface $output): int - { - $context = Context::createCLIContext(); - $refreshRateMs = (int) $input->getOption('refreshRate'); - if ($refreshRateMs < 250) { - $refreshRateMs = 250; - $output->writeln('refreshRates smaller than 250ms are not supported, falling back to 250ms.'); - } - - $migrationState = $this->runService->getRunStatus($context); - - if ($migrationState->getStep() === MigrationStep::IDLE) { - $output->writeln('Currently there is no migration running'); - - return Command::FAILURE; - } - - $progressBar = new ProgressBar($output, $migrationState->getTotal()); - $progressBar->setFormat(self::PROGRESSBAR_FORMAT . $migrationState->getStepValue()); - $progressBar->setMaxSteps($migrationState->getTotal()); - $progressBar->setProgress($migrationState->getProgress()); - - while ($migrationState->getStep() !== MigrationStep::FINISHED) { - $migrationState = $this->runService->getRunStatus($context); - - if ($migrationState->getStep() === MigrationStep::IDLE) { - $output->writeln(''); - $output->writeln('Migration was aborted.'); - - break; - } - - if ($migrationState->getStep() === MigrationStep::WAITING_FOR_APPROVE) { - $this->runService->approveFinishingMigration($context); - $output->writeln(''); - $output->writeln('Migration is finished.'); - - break; - } - - $progressBar->setFormat(self::PROGRESSBAR_FORMAT . $migrationState->getStepValue()); - $progressBar->setMaxSteps($migrationState->getTotal()); - $progressBar->setProgress($migrationState->getProgress()); - - \usleep($refreshRateMs * 1000); - } - - return Command::SUCCESS; - } -} diff --git a/src/Command/StartMigrationCommand.php b/src/Command/StartMigrationCommand.php deleted file mode 100644 index 79be7fb01..000000000 --- a/src/Command/StartMigrationCommand.php +++ /dev/null @@ -1,88 +0,0 @@ - - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace SwagMigrationAssistant\Command; - -use Shopware\Core\Framework\Context; -use Shopware\Core\Framework\Log\Package; -use SwagMigrationAssistant\Exception\MigrationIsAlreadyRunningException; -use SwagMigrationAssistant\Exception\PremappingIsIncompleteException; -use SwagMigrationAssistant\Migration\Run\RunServiceInterface; -use SwagMigrationAssistant\Profile\Shopware\DataSelection\BasicSettingsDataSelection; -use Symfony\Component\Console\Attribute\AsCommand; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -#[Package('fundamentals@after-sales')] -#[AsCommand( - name: 'migration:start', - description: 'Migrate the data of your selected source to Shopware 6. Before you execute this command - you have to configure the migration in the Shopware 6 administration.', -)] -class StartMigrationCommand extends Command -{ - /** - * @var string[] - */ - private array $dataSelectionNames = []; - - public function __construct( - private readonly RunServiceInterface $runService, - ?string $name = null, - ) { - parent::__construct($name); - } - - protected function configure(): void - { - $this->addArgument('dataSelections', InputArgument::IS_ARRAY | InputArgument::REQUIRED); - } - - protected function execute(InputInterface $input, OutputInterface $output): int - { - $context = Context::createCLIContext(); - - if (!$this->validateDataSelections($input)) { - $output->writeln('Please provide at least one data selection.'); - - return Command::FAILURE; - } - - try { - $this->runService->startMigrationRun($this->dataSelectionNames, $context); - } catch (MigrationIsAlreadyRunningException $exception) { - $output->writeln('Migration is already running, please use `migration:get-progress` to check the progress.'); - - return Command::FAILURE; - } catch (PremappingIsIncompleteException $exception) { - $output->writeln('Premapping is incomplete, please fill it in before performing the migration.'); - - return Command::FAILURE; - } - - $output->writeln('Migration is started, please use migration:get-progress to check the progress.'); - - return Command::SUCCESS; - } - - private function validateDataSelections(InputInterface $input): bool - { - $dataSelections = $input->getArgument('dataSelections'); - if (!$dataSelections) { - return false; - } - if (!\is_array($dataSelections)) { - $dataSelections = [$dataSelections]; - } - $this->dataSelectionNames[] = BasicSettingsDataSelection::IDENTIFIER; - $this->dataSelectionNames = \array_merge($this->dataSelectionNames, $dataSelections); - - return true; - } -} diff --git a/src/Controller/HistoryController.php b/src/Controller/HistoryController.php index 20800612f..2503bfa77 100644 --- a/src/Controller/HistoryController.php +++ b/src/Controller/HistoryController.php @@ -12,6 +12,7 @@ use Shopware\Core\Framework\Routing\RoutingException; use SwagMigrationAssistant\Exception\MigrationException; use SwagMigrationAssistant\Migration\History\HistoryServiceInterface; +use SwagMigrationAssistant\Migration\History\LogGroupingServiceInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\HeaderUtils; use Symfony\Component\HttpFoundation\JsonResponse; @@ -25,11 +26,13 @@ #[Package('fundamentals@after-sales')] class HistoryController extends AbstractController { - public function __construct(private readonly HistoryServiceInterface $historyService) - { + public function __construct( + private readonly HistoryServiceInterface $historyService, + private readonly LogGroupingServiceInterface $logGroupingService, + ) { } - #[Route(path: '/api/migration/get-grouped-logs-of-run', name: 'api.admin.migration.get-grouped-logs-of-run', methods: ['GET'], defaults: ['_acl' => ['admin']])] + #[Route(path: '/api/_action/migration/get-grouped-logs-of-run', name: 'api.admin.migration.get-grouped-logs-of-run', methods: ['GET'], defaults: ['_acl' => ['swag_migration.viewer']])] public function getGroupedLogsOfRun(Request $request, Context $context): JsonResponse { $runUuid = $request->query->getAlnum('runUuid'); @@ -54,7 +57,7 @@ public function getGroupedLogsOfRun(Request $request, Context $context): JsonRes ]); } - #[Route(path: '/api/_action/migration/download-logs-of-run', name: 'api.admin.migration.download-logs-of-run', methods: ['POST'], defaults: ['auth_required' => false, '_acl' => ['admin']])] + #[Route(path: '/api/_action/migration/download-logs-of-run', name: 'api.admin.migration.download-logs-of-run', methods: ['POST'], defaults: ['auth_required' => false, '_acl' => ['swag_migration.viewer']])] public function downloadLogsOfRun(Request $request, Context $context): StreamedResponse { $runUuid = $request->request->getAlnum('runUuid'); @@ -80,7 +83,7 @@ public function downloadLogsOfRun(Request $request, Context $context): StreamedR return $response; } - #[Route(path: '/api/_action/migration/clear-data-of-run', name: 'api.admin.migration.clear-data-of-run', methods: ['POST'], defaults: ['_acl' => ['admin']])] + #[Route(path: '/api/_action/migration/clear-data-of-run', name: 'api.admin.migration.clear-data-of-run', methods: ['POST'], defaults: ['_acl' => ['swag_migration.deleter']])] public function clearDataOfRun(Request $request, Context $context): Response { $runUuid = $request->request->getAlnum('runUuid'); @@ -98,11 +101,109 @@ public function clearDataOfRun(Request $request, Context $context): Response return new Response(); } - #[Route(path: '/api/_action/migration/is-media-processing', name: 'api.admin.migration.is-media-processing', methods: ['GET'], defaults: ['_acl' => ['admin']])] + #[Route(path: '/api/_action/migration/is-media-processing', name: 'api.admin.migration.is-media-processing', methods: ['GET'], defaults: ['_acl' => ['swag_migration_history:read']])] public function isMediaProcessing(): JsonResponse { $result = $this->historyService->isMediaProcessing(); return new JsonResponse($result); } + + #[Route( + path: '/api/_action/migration/get-log-groups', + name: 'api.admin.migration.get-log-groups', + methods: ['GET'], + defaults: ['_acl' => ['swag_migration.viewer']] + )] + public function getLogGroups(Request $request, Context $context): JsonResponse + { + $runId = $request->query->getAlnum('runId'); + + if (empty($runId)) { + throw RoutingException::missingRequestParameter('runId'); + } + + $level = $request->query->getAlpha('level'); + + if (empty($level)) { + throw RoutingException::missingRequestParameter('level'); + } + + $page = $request->query->getInt('page', 1); + $limit = $request->query->getInt('limit', 25); + + $sortBy = $request->query->getAlpha('sortBy') ?: 'count'; + $sortDirection = $request->query->getAlpha('sortDirection') ?: 'DESC'; + + if (!\in_array(\strtoupper($sortDirection), ['ASC', 'DESC'], true)) { + $sortDirection = 'DESC'; + } + + $filterCode = $request->query->get('filterCode'); + $filterStatus = $request->query->get('filterStatus'); + $filterEntity = $request->query->get('filterEntity'); + $filterField = $request->query->get('filterField'); + + $result = $this->logGroupingService->getGroupedLogsByCodeAndEntity( + $runId, + $level, + $page, + $limit, + $sortBy, + \strtoupper($sortDirection), + \is_string($filterCode) && !empty($filterCode) ? $filterCode : null, + \is_string($filterStatus) && !empty($filterStatus) ? $filterStatus : null, + \is_string($filterEntity) && !empty($filterEntity) ? $filterEntity : null, + \is_string($filterField) && !empty($filterField) ? $filterField : null, + ); + + return new JsonResponse($result); + } + + #[Route( + path: '/api/_action/migration/get-all-log-ids', + name: 'api.admin.migration.get-all-log-ids', + methods: ['POST'], + defaults: ['_acl' => ['swag_migration.viewer']] + )] + public function getAllLogIds(Request $request): JsonResponse + { + $runId = $request->request->getAlnum('runId'); + + if (empty($runId)) { + throw RoutingException::missingRequestParameter('runId'); + } + + $code = $request->request->get('code'); + + if (!\is_string($code) || empty($code)) { + throw RoutingException::missingRequestParameter('code'); + } + + $entityName = $request->request->get('entityName'); + + if (!\is_string($entityName) || empty($entityName)) { + throw RoutingException::missingRequestParameter('entityName'); + } + + $fieldName = $request->request->get('fieldName'); + + if (!\is_string($fieldName) || empty($fieldName)) { + throw RoutingException::missingRequestParameter('fieldName'); + } + + $connectionId = $request->request->getAlnum('connectionId'); + + $logIds = $this->logGroupingService->getAllLogIdsByCodeAndEntity( + $runId, + $code, + $entityName, + $fieldName, + !empty($connectionId) ? $connectionId : null + ); + + return new JsonResponse([ + 'ids' => $logIds, + ]); + } } diff --git a/src/Controller/PremappingController.php b/src/Controller/PremappingController.php index 87f33621a..9f73e6068 100644 --- a/src/Controller/PremappingController.php +++ b/src/Controller/PremappingController.php @@ -28,7 +28,7 @@ public function __construct( ) { } - #[Route(path: '/api/_action/migration/generate-premapping', name: 'api.admin.migration.generate-premapping', methods: ['POST'], defaults: ['_acl' => ['admin']])] + #[Route(path: '/api/_action/migration/generate-premapping', name: 'api.admin.migration.generate-premapping', methods: ['POST'], defaults: ['_acl' => ['swag_migration.editor']])] public function generatePremapping(Request $request, Context $context): JsonResponse { $dataSelectionIds = $request->request->all('dataSelectionIds'); @@ -41,7 +41,7 @@ public function generatePremapping(Request $request, Context $context): JsonResp return new JsonResponse($this->premappingService->generatePremapping($context, $migrationContext, $dataSelectionIds)); } - #[Route(path: '/api/_action/migration/write-premapping', name: 'api.admin.migration.write-premapping', methods: ['POST'], defaults: ['_acl' => ['admin']])] + #[Route(path: '/api/_action/migration/write-premapping', name: 'api.admin.migration.write-premapping', methods: ['POST'], defaults: ['_acl' => ['swag_migration.editor']])] public function writePremapping(Request $request, Context $context): Response { $premapping = $request->request->all('premapping'); diff --git a/src/Controller/StatusController.php b/src/Controller/StatusController.php index 65af65ab1..66de83eac 100644 --- a/src/Controller/StatusController.php +++ b/src/Controller/StatusController.php @@ -14,8 +14,10 @@ use Shopware\Core\Framework\Routing\RoutingException; use SwagMigrationAssistant\Exception\MigrationException; use SwagMigrationAssistant\Migration\Connection\SwagMigrationConnectionCollection; +use SwagMigrationAssistant\Migration\Connection\SwagMigrationConnectionEntity; use SwagMigrationAssistant\Migration\DataSelection\DataSelectionRegistryInterface; use SwagMigrationAssistant\Migration\Gateway\GatewayRegistryInterface; +use SwagMigrationAssistant\Migration\MigrationContext; use SwagMigrationAssistant\Migration\MigrationContextFactoryInterface; use SwagMigrationAssistant\Migration\Profile\ProfileRegistryInterface; use SwagMigrationAssistant\Migration\Run\RunServiceInterface; @@ -50,7 +52,7 @@ public function __construct( #[Route( path: '/api/_action/migration/get-profile-information', name: 'api.admin.migration.get-profile-information', - defaults: ['_acl' => ['admin']], + defaults: ['_acl' => ['swag_migration.viewer']], methods: [Request::METHOD_GET] )] public function getProfileInformation(Request $request): Response @@ -87,8 +89,11 @@ public function getProfileInformation(Request $request): Response return new Response(); } - $migrationContext = $this->migrationContextFactory->createByProfileName($profileName); - $gateways = $this->gatewayRegistry->getGateways($migrationContext); + $profile = $this->profileRegistry->getProfile($profileName); + $context = new MigrationContext(new SwagMigrationConnectionEntity()); + $context->setProfile($profile); + + $gateways = $this->gatewayRegistry->getGateways($context); $currentGateway = null; foreach ($gateways as $gateway) { @@ -117,7 +122,7 @@ public function getProfileInformation(Request $request): Response #[Route( path: '/api/_action/migration/get-profiles', name: 'api.admin.migration.get-profiles', - defaults: ['_acl' => ['admin']], + defaults: ['_acl' => ['swag_migration.viewer']], methods: [Request::METHOD_GET] )] public function getProfiles(): JsonResponse @@ -140,7 +145,7 @@ public function getProfiles(): JsonResponse #[Route( path: '/api/_action/migration/get-gateways', name: 'api.admin.migration.get-gateways', - defaults: ['_acl' => ['admin']], + defaults: ['_acl' => ['swag_migration.viewer']], methods: [Request::METHOD_GET] )] public function getGateways(Request $request): JsonResponse @@ -151,8 +156,11 @@ public function getGateways(Request $request): JsonResponse throw RoutingException::missingRequestParameter('profileName'); } - $migrationContext = $this->migrationContextFactory->createByProfileName($profileName); - $gateways = $this->gatewayRegistry->getGateways($migrationContext); + $profile = $this->profileRegistry->getProfile($profileName); + $context = new MigrationContext(new SwagMigrationConnectionEntity()); + $context->setProfile($profile); + + $gateways = $this->gatewayRegistry->getGateways($context); $gatewayNames = []; foreach ($gateways as $gateway) { @@ -168,7 +176,7 @@ public function getGateways(Request $request): JsonResponse #[Route( path: '/api/_action/migration/update-connection-credentials', name: 'api.admin.migration.update-connection-credentials', - defaults: ['_acl' => ['admin']], + defaults: ['_acl' => ['swag_migration.editor']], methods: [Request::METHOD_POST] )] public function updateConnectionCredentials(Request $request, Context $context): Response @@ -195,7 +203,7 @@ public function updateConnectionCredentials(Request $request, Context $context): #[Route( path: '/api/_action/migration/data-selection', name: 'api.admin.migration.data-selection', - defaults: ['_acl' => ['admin']], + defaults: ['_acl' => ['swag_migration.viewer']], methods: [Request::METHOD_GET] )] public function getDataSelection(Request $request, Context $context): JsonResponse @@ -222,7 +230,7 @@ public function getDataSelection(Request $request, Context $context): JsonRespon #[Route( path: '/api/_action/migration/check-connection', name: 'api.admin.migration.check-connection', - defaults: ['_acl' => ['admin']], + defaults: ['_acl' => ['swag_migration.viewer']], methods: [Request::METHOD_POST] )] public function checkConnection(Request $request, Context $context): JsonResponse @@ -248,7 +256,7 @@ public function checkConnection(Request $request, Context $context): JsonRespons #[Route( path: '/api/_action/migration/start-migration', name: 'api.admin.migration.start-migration', - defaults: ['_acl' => ['admin']], + defaults: ['_acl' => ['swag_migration.creator']], methods: [Request::METHOD_POST] )] public function startMigration(Request $request, Context $context): Response @@ -281,7 +289,7 @@ public function startMigration(Request $request, Context $context): Response #[Route( path: '/api/_action/migration/get-state', name: 'api.admin.migration.get-state', - defaults: ['_acl' => ['admin']], + defaults: ['_acl' => ['swag_migration.viewer']], methods: [Request::METHOD_GET] )] public function getState(Context $context): JsonResponse @@ -292,7 +300,7 @@ public function getState(Context $context): JsonResponse #[Route( path: '/api/_action/migration/approve-finished', name: 'api.admin.migration.approveFinished', - defaults: ['_acl' => ['admin']], + defaults: ['_acl' => ['swag_migration.editor']], methods: [Request::METHOD_POST] )] public function approveFinishedMigration(Context $context): Response @@ -313,16 +321,12 @@ public function approveFinishedMigration(Context $context): Response #[Route( path: '/api/_action/migration/abort-migration', name: 'api.admin.migration.abort-migration', - defaults: ['_acl' => ['admin']], + defaults: ['_acl' => ['swag_migration.editor']], methods: [Request::METHOD_POST] )] public function abortMigration(Context $context): Response { - try { - $this->runService->abortMigration($context); - } catch (\Exception $e) { - return new Response($e->getMessage(), Response::HTTP_BAD_REQUEST); - } + $this->runService->abortMigration($context); return new Response(null, Response::HTTP_NO_CONTENT); } @@ -330,7 +334,7 @@ public function abortMigration(Context $context): Response #[Route( path: '/api/_action/migration/reset-checksums', name: 'api.admin.migration.reset-checksums', - defaults: ['_acl' => ['admin']], + defaults: ['_acl' => ['swag_migration.deleter']], methods: [Request::METHOD_POST] )] public function resetChecksums(Request $request, Context $context): Response @@ -341,14 +345,7 @@ public function resetChecksums(Request $request, Context $context): Response throw RoutingException::missingRequestParameter('connectionId'); } - $connection = $this->migrationConnectionRepo->search(new Criteria([$connectionId]), $context)->getEntities()->first(); - - if ($connection === null) { - throw MigrationException::noConnectionFound(); - } - - // ToDo: MIG-965 - Check how we could put this into the MQ - $this->runService->cleanupMappingChecksums($connectionId, $context); + $this->runService->startCleanupMappingChecksums($connectionId, $context); return new Response(); } @@ -356,23 +353,23 @@ public function resetChecksums(Request $request, Context $context): Response #[Route( path: '/api/_action/migration/cleanup-migration-data', name: 'api.admin.migration.cleanup-migration-data', - defaults: ['_acl' => ['admin']], + defaults: ['_acl' => ['swag_migration.deleter']], methods: [Request::METHOD_POST] )] public function cleanupMigrationData(Context $context): Response { - $this->runService->cleanupMigrationData($context); + $this->runService->startTruncateMigrationData($context); return new Response(); } #[Route( - path: '/api/_action/migration/get-reset-status', + path: '/api/_action/migration/is-truncating-migration-data', name: 'api.admin.migration.get-reset-status', - defaults: ['_acl' => ['admin']], + defaults: ['_acl' => ['swag_migration.viewer']], methods: [Request::METHOD_GET] )] - public function getResetStatus(Context $context): JsonResponse + public function isTruncatingMigrationData(Context $context): JsonResponse { $settings = $this->generalSettingRepo->search(new Criteria(), $context)->getEntities()->first(); @@ -382,4 +379,39 @@ public function getResetStatus(Context $context): JsonResponse return new JsonResponse($settings->isReset()); } + + #[Route( + path: '/api/_action/migration/is-resetting-checksums', + name: 'api.admin.migration.is-resetting-checksums', + defaults: ['_acl' => ['swag_migration.viewer']], + methods: [Request::METHOD_GET] + )] + public function isResettingChecksums(Context $context): JsonResponse + { + $settings = $this->generalSettingRepo + ->search(new Criteria(), $context) + ->getEntities() + ->first(); + + if ($settings === null) { + return new JsonResponse(false); + } + + return new JsonResponse( + $settings->isResettingChecksums() + ); + } + + #[Route( + path: '/api/_action/migration/resume-after-fixes', + name: 'api.admin.migration.resume-after-fixes', + defaults: ['_acl' => ['admin']], + methods: [Request::METHOD_POST] + )] + public function resumeAfterFixes(Context $context): Response + { + $this->runService->resumeAfterFixes($context); + + return new Response(null, Response::HTTP_NO_CONTENT); + } } diff --git a/src/Core/Field/AnyJsonField.php b/src/Core/Field/AnyJsonField.php new file mode 100644 index 000000000..a6c8de7bd --- /dev/null +++ b/src/Core/Field/AnyJsonField.php @@ -0,0 +1,41 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Core\Field; + +use Shopware\Core\Framework\DataAbstractionLayer\Field\Field; +use Shopware\Core\Framework\DataAbstractionLayer\Field\StorageAware; +use Shopware\Core\Framework\Log\Package; + +/** + * This is an alternative for the JsonField and allows to save all simple data types + * into a JSON database field, not just arrays. + * + * int, float, string, null and array + * + * @internal + */ +#[Package('fundamentals@after-sales')] +class AnyJsonField extends Field implements StorageAware +{ + public function __construct( + private readonly string $storageName, + string $propertyName, + ) { + parent::__construct($propertyName); + } + + public function getStorageName(): string + { + return $this->storageName; + } + + protected function getSerializerClass(): string + { + return AnyJsonFieldSerializer::class; + } +} diff --git a/src/Core/Field/AnyJsonFieldSerializer.php b/src/Core/Field/AnyJsonFieldSerializer.php new file mode 100644 index 000000000..88e9b2096 --- /dev/null +++ b/src/Core/Field/AnyJsonFieldSerializer.php @@ -0,0 +1,46 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Core\Field; + +use Shopware\Core\Framework\DataAbstractionLayer\DataAbstractionLayerException; +use Shopware\Core\Framework\DataAbstractionLayer\Field\Field; +use Shopware\Core\Framework\DataAbstractionLayer\FieldSerializer\AbstractFieldSerializer; +use Shopware\Core\Framework\DataAbstractionLayer\Write\DataStack\KeyValuePair; +use Shopware\Core\Framework\DataAbstractionLayer\Write\EntityExistence; +use Shopware\Core\Framework\DataAbstractionLayer\Write\WriteParameterBag; +use Shopware\Core\Framework\Log\Package; +use Shopware\Core\Framework\Util\Json; + +/** + * @internal + */ +#[Package('fundamentals@after-sales')] +class AnyJsonFieldSerializer extends AbstractFieldSerializer +{ + public function encode(Field $field, EntityExistence $existence, KeyValuePair $data, WriteParameterBag $parameters): \Generator + { + if (!$field instanceof AnyJsonField) { + throw DataAbstractionLayerException::invalidSerializerField(AnyJsonField::class, $field); + } + + $value = $data->getValue(); + + $value = Json::encode($value); + + yield $field->getStorageName() => $value; + } + + public function decode(Field $field, mixed $value): mixed + { + if (!$field instanceof AnyJsonField) { + throw DataAbstractionLayerException::invalidSerializerField(AnyJsonField::class, $field); + } + + return json_decode($value, true, 512, \JSON_THROW_ON_ERROR); + } +} diff --git a/src/Core/Migration/Migration1754896654TruncateMigrationLogs.php b/src/Core/Migration/Migration1754896654TruncateMigrationLogs.php new file mode 100644 index 000000000..76077ebaf --- /dev/null +++ b/src/Core/Migration/Migration1754896654TruncateMigrationLogs.php @@ -0,0 +1,29 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Core\Migration; + +use Doctrine\DBAL\Connection; +use Shopware\Core\Framework\Log\Package; +use Shopware\Core\Framework\Migration\MigrationStep; + +/** + * @internal + */ +#[Package('fundamentals@after-sales')] +class Migration1754896654TruncateMigrationLogs extends MigrationStep +{ + public function getCreationTimestamp(): int + { + return 1754896654; + } + + public function update(Connection $connection): void + { + $connection->executeStatement('TRUNCATE TABLE `swag_migration_logging`'); + } +} diff --git a/src/Core/Migration/Migration1754897550AddFieldsToMigrationLogs.php b/src/Core/Migration/Migration1754897550AddFieldsToMigrationLogs.php new file mode 100644 index 000000000..5cc64860a --- /dev/null +++ b/src/Core/Migration/Migration1754897550AddFieldsToMigrationLogs.php @@ -0,0 +1,198 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Core\Migration; + +use Doctrine\DBAL\Connection; +use Doctrine\DBAL\Exception; +use Doctrine\DBAL\Platforms\MySQLPlatform; +use Doctrine\DBAL\Schema\AbstractSchemaManager; +use Shopware\Core\Framework\Log\Package; +use Shopware\Core\Framework\Migration\MigrationStep; + +/** + * @internal + */ +#[Package('fundamentals@after-sales')] +class Migration1754897550AddFieldsToMigrationLogs extends MigrationStep +{ + public const MIGRATION_LOGGING_TABLE = 'swag_migration_logging'; + + public const REQUIRED_FIELDS = [ + 'id' => 'BINARY(16) NOT NULL', + 'run_id' => 'BINARY(16) NULL', + 'profile_name' => 'VARCHAR(64) NOT NULL', + 'gateway_name' => 'VARCHAR(64) NOT NULL', + 'level' => 'VARCHAR(64) NOT NULL', + 'code' => 'VARCHAR(255) NOT NULL', + 'user_fixable' => 'TINYINT(1) NOT NULL DEFAULT 0', + ]; + + public const OPTIONAL_FIELDS = [ + 'entity_name' => 'VARCHAR(64) NULL', + 'entity_id' => 'BINARY(16) NULL', + 'field_name' => 'VARCHAR(64) NULL', + 'field_source_path' => 'VARCHAR(255) NULL', + 'source_data' => 'JSON NULL', + 'converted_data' => 'JSON NULL', + 'exception_message' => 'VARCHAR(255) NULL', + 'exception_trace' => 'JSON NULL', + ]; + + public const SYSTEM_FIELDS = [ + 'auto_increment' => 'BIGINT UNSIGNED AUTO_INCREMENT UNIQUE', + 'created_at' => 'DATETIME(3) NOT NULL', + 'updated_at' => 'DATETIME(3) NULL', + ]; + + public const FIELDS_TO_DROP = [ + 'title', + 'description', + 'parameters', + 'title_snippet', + 'description_snippet', + 'entity', + 'source_id', + ]; + + public function getCreationTimestamp(): int + { + return 1754897550; + } + + /** + * @throws \Throwable + */ + public function update(Connection $connection): void + { + $schemaManager = $connection->createSchemaManager(); + + if (!$schemaManager->tablesExist([self::MIGRATION_LOGGING_TABLE])) { + return; + } + + $this->dropForeignKeyIfExists($connection, self::MIGRATION_LOGGING_TABLE, 'fk.swag_migration_logging.run_id'); + $this->dropIndexIfExists($connection, self::MIGRATION_LOGGING_TABLE, 'idx.swag_migration_logging.run_id_code'); + $this->dropConstraintIfExists($connection, 'json.swag_migration_logging.log_entry'); + + $this->dropObsoleteColumns($connection); + $this->addOrModifyColumns($connection, $schemaManager); + $this->ensureRelations($connection, $schemaManager); + } + + private function dropObsoleteColumns(Connection $connection): void + { + foreach (self::FIELDS_TO_DROP as $column) { + $this->dropColumnIfExists($connection, 'swag_migration_logging', $column); + } + } + + /** + * @param AbstractSchemaManager $schemaManager + */ + private function addOrModifyColumns(Connection $connection, AbstractSchemaManager $schemaManager): void + { + $columns = $schemaManager->listTableColumns(self::MIGRATION_LOGGING_TABLE); + + $orderedFields = array_merge( + self::REQUIRED_FIELDS, + self::OPTIONAL_FIELDS, + self::SYSTEM_FIELDS + ); + + foreach ($orderedFields as $name => $type) { + if (!isset($columns[$name])) { + $connection->executeStatement( + \sprintf( + 'ALTER TABLE `%s` ADD COLUMN `%s` %s;', + self::MIGRATION_LOGGING_TABLE, + $name, + $type + ) + ); + } else { + $connection->executeStatement( + \sprintf( + 'ALTER TABLE `%s` MODIFY COLUMN `%s` %s;', + self::MIGRATION_LOGGING_TABLE, + $name, + $type + ) + ); + } + } + } + + /** + * @param AbstractSchemaManager $schemaManager + */ + private function ensureRelations(Connection $connection, AbstractSchemaManager $schemaManager): void + { + // ensure primary key and index + $indexes = $schemaManager->listTableIndexes(self::MIGRATION_LOGGING_TABLE); + + if (isset($indexes['primary'])) { + $connection->executeStatement( + \sprintf( + 'ALTER TABLE `%s` DROP PRIMARY KEY;', + self::MIGRATION_LOGGING_TABLE + ) + ); + } + + $connection->executeStatement( + \sprintf( + 'ALTER TABLE `%s` ADD PRIMARY KEY (`id`);', + self::MIGRATION_LOGGING_TABLE + ) + ); + + $this->dropIndexIfExists( + $connection, + self::MIGRATION_LOGGING_TABLE, + 'idx.run_id' + ); + $connection->executeStatement( + \sprintf( + 'ALTER TABLE `%s` ADD INDEX `idx.run_id` (`run_id`);', + self::MIGRATION_LOGGING_TABLE + ) + ); + + // ensure entity_id index + if (!$this->indexExists($connection, self::MIGRATION_LOGGING_TABLE, 'idx.entity_id')) { + $connection->executeStatement( + \sprintf( + 'ALTER TABLE `%s` ADD INDEX `idx.entity_id` (`entity_id`);', + self::MIGRATION_LOGGING_TABLE + ) + ); + } + + // ensure foreign key constraint + $connection->executeStatement( + \sprintf( + 'ALTER TABLE `%s` ADD CONSTRAINT `fk.swag_migration_logging.run_id` FOREIGN KEY (`run_id`) REFERENCES `swag_migration_run` (`id`) ON DELETE RESTRICT ON UPDATE CASCADE;', + self::MIGRATION_LOGGING_TABLE + ) + ); + } + + private function dropConstraintIfExists(Connection $connection, string $constraintName): void + { + try { + $connection->executeStatement( + \sprintf( + 'ALTER TABLE `%s` DROP CONSTRAINT `%s`;', + self::MIGRATION_LOGGING_TABLE, + $constraintName + ) + ); + } catch (Exception) { + } + } +} diff --git a/src/Core/Migration/Migration1757598733AddMigrationFixesTable.php b/src/Core/Migration/Migration1757598733AddMigrationFixesTable.php new file mode 100644 index 000000000..8d2b23c5a --- /dev/null +++ b/src/Core/Migration/Migration1757598733AddMigrationFixesTable.php @@ -0,0 +1,57 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Core\Migration; + +use Doctrine\DBAL\Connection; +use Shopware\Core\Framework\Log\Package; +use Shopware\Core\Framework\Migration\MigrationStep; + +/** + * @internal + */ +#[Package('fundamentals@after-sales')] +class Migration1757598733AddMigrationFixesTable extends MigrationStep +{ + public const MIGRATION_FIXES_TABLE = 'swag_migration_fix'; + + public const FIELDS = [ + 'id' => 'BINARY(16) NOT NULL', + 'connection_id' => 'BINARY(16) NOT NULL', + 'value' => 'JSON NOT NULL', + 'path' => 'VARCHAR(255) NOT NULL', + 'entity_name' => 'VARCHAR(255) NULL', + 'entity_id' => 'BINARY(16) NULL', + 'created_at' => 'DATETIME(3) NOT NULL', + 'updated_at' => 'DATETIME(3) NULL', + ]; + + public function getCreationTimestamp(): int + { + return 1757598733; + } + + public function update(Connection $connection): void + { + $columns = []; + + foreach (self::FIELDS as $name => $definition) { + $columns[] = "`$name` $definition"; + } + + $sql = \sprintf(' + CREATE TABLE IF NOT EXISTS `%s` ( + %s, + PRIMARY KEY (`id`), + CONSTRAINT `fk.swag_migration_fix.connection_id` FOREIGN KEY (`connection_id`) REFERENCES `swag_migration_connection` (`id`) ON DELETE CASCADE, + INDEX `idx.entity_id` (`entity_id`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + ', self::MIGRATION_FIXES_TABLE, implode(', ', $columns)); + + $connection->executeStatement($sql); + } +} diff --git a/src/Core/Migration/Migration1759000000AddIsResettingChecksumsToSetting.php b/src/Core/Migration/Migration1759000000AddIsResettingChecksumsToSetting.php new file mode 100644 index 000000000..f2ece4927 --- /dev/null +++ b/src/Core/Migration/Migration1759000000AddIsResettingChecksumsToSetting.php @@ -0,0 +1,37 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Core\Migration; + +use Doctrine\DBAL\Connection; +use Shopware\Core\Framework\Log\Package; +use Shopware\Core\Framework\Migration\MigrationStep; + +#[Package('fundamentals@after-sales')] +class Migration1759000000AddIsResettingChecksumsToSetting extends MigrationStep +{ + public const TABLE = 'swag_migration_general_setting'; + + public const COLUMN = 'is_resetting_checksums'; + + public function getCreationTimestamp(): int + { + return 1759000000; + } + + public function update(Connection $connection): void + { + $this->addColumn( + connection: $connection, + table: self::TABLE, + column: self::COLUMN, + type: 'TINYINT(1)', + nullable: false, + default: '0' + ); + } +} diff --git a/src/Core/Migration/Migration1762346793RenameColumnOfMappingTable.php b/src/Core/Migration/Migration1762346793RenameColumnOfMappingTable.php new file mode 100644 index 000000000..7466fce56 --- /dev/null +++ b/src/Core/Migration/Migration1762346793RenameColumnOfMappingTable.php @@ -0,0 +1,40 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Core\Migration; + +use Doctrine\DBAL\Connection; +use Shopware\Core\Framework\Log\Package; +use Shopware\Core\Framework\Migration\ColumnExistsTrait; +use Shopware\Core\Framework\Migration\MigrationStep; + +/** + * @internal + */ +#[Package('fundamentals@after-sales')] +class Migration1762346793RenameColumnOfMappingTable extends MigrationStep +{ + use ColumnExistsTrait; + + public function getCreationTimestamp(): int + { + return 1762346793; + } + + public function update(Connection $connection): void + { + if ($this->columnExists($connection, 'swag_migration_mapping', 'entity_id')) { + return; + } + + if (!$this->columnExists($connection, 'swag_migration_mapping', 'entity_uuid')) { + return; + } + + $connection->executeStatement('ALTER TABLE `swag_migration_mapping` CHANGE `entity_uuid` `entity_id` BINARY(16)'); + } +} diff --git a/src/DataProvider/Provider/Data/OrderProvider.php b/src/DataProvider/Provider/Data/OrderProvider.php index 49742f82f..5b1a367dd 100644 --- a/src/DataProvider/Provider/Data/OrderProvider.php +++ b/src/DataProvider/Provider/Data/OrderProvider.php @@ -66,7 +66,6 @@ public function getProvidedData(int $limit, int $offset, Context $context): arra $row['positionPrice'] ); - // ToDo MIG-902: properly migrate this association if (!empty($row['lineItems'])) { foreach ($row['lineItems'] as &$lineItem) { unset($lineItem['promotionId']); diff --git a/src/DataProvider/Provider/Data/ProductProvider.php b/src/DataProvider/Provider/Data/ProductProvider.php index 15f279c38..a2aff026d 100644 --- a/src/DataProvider/Provider/Data/ProductProvider.php +++ b/src/DataProvider/Provider/Data/ProductProvider.php @@ -86,10 +86,9 @@ public function getProvidedData(int $limit, int $offset, Context $context): arra 'thumbnails', 'thumbnailsRo', 'hasFile', - 'userId', // maybe put back in, if we migrate users - - 'canonicalProductId', // ToDo MIG-900: properly migrate this association in a separate DataSet - 'cmsPageId', // ToDo MIG-901: properly migrate this association in a separate DataSet + 'userId', + 'canonicalProductId', + 'cmsPageId', ]); foreach ($cleanResult as &$product) { diff --git a/src/DependencyInjection/entity.xml b/src/DependencyInjection/entity.xml index a74cc13ac..170b23118 100644 --- a/src/DependencyInjection/entity.xml +++ b/src/DependencyInjection/entity.xml @@ -45,5 +45,16 @@ + + + + + + + + + + + diff --git a/src/DependencyInjection/migration.xml b/src/DependencyInjection/migration.xml index b67dc462e..22f83d773 100644 --- a/src/DependencyInjection/migration.xml +++ b/src/DependencyInjection/migration.xml @@ -185,7 +185,6 @@ - @@ -199,6 +198,10 @@ + + + + @@ -222,6 +225,7 @@ + @@ -232,6 +236,7 @@ + @@ -278,27 +283,13 @@ + - - - - - - - - - - - - - - - @@ -326,7 +317,7 @@ - + @@ -342,7 +333,14 @@ + + + + + + + @@ -382,7 +380,6 @@ - @@ -418,5 +415,12 @@ + + + + + + + diff --git a/src/DependencyInjection/shopware.xml b/src/DependencyInjection/shopware.xml index b893496aa..77f6e4503 100644 --- a/src/DependencyInjection/shopware.xml +++ b/src/DependencyInjection/shopware.xml @@ -212,8 +212,8 @@ - + + + + + diff --git a/src/Exception/MigrationException.php b/src/Exception/MigrationException.php index 5eeee646b..e61c946ff 100644 --- a/src/Exception/MigrationException.php +++ b/src/Exception/MigrationException.php @@ -32,6 +32,10 @@ class MigrationException extends HttpException public const MIGRATION_IS_ALREADY_RUNNING = 'SWAG_MIGRATION__MIGRATION_IS_ALREADY_RUNNING'; + public const MIGRATION_IS_RESETTING_CHECKSUMS = 'SWAG_MIGRATION__MIGRATION_IS_RESETTING_CHECKSUMS'; + + public const MIGRATION_IS_TRUNCATING_DATA = 'SWAG_MIGRATION__MIGRATION_IS_TRUNCATING_DATA'; + public const NO_CONNECTION_IS_SELECTED = 'SWAG_MIGRATION__NO_CONNECTION_IS_SELECTED'; public const NO_CONNECTION_FOUND = 'SWAG_MIGRATION__NO_CONNECTION_FOUND'; @@ -96,6 +100,16 @@ class MigrationException extends HttpException public const API_CONNECTION_ERROR = 'SWAG_MIGRATION__API_CONNECTION_ERROR'; + public const FAILED_TO_CREATE_MIGRATION_LOG = 'SWAG_MIGRATION__FAILED_TO_CREATE_MIGRATION_LOG'; + + public const UNEXPECTED_NULL_VALUE = 'SWAG_MIGRATION__UNEXPECTED_NULL_VALUE'; + + public const MISSING_MIGRATION_FIX_KEY = 'SWAG_MIGRATION__MISSING_MIGRATION_FIX_KEY'; + + public const MIGRATION_NOT_IN_STEP = 'SWAG_MIGRATION__MIGRATION_NOT_IN_STEP'; + + public const INVALID_ID = 'SWAG_MIGRATION__INVALID_ID'; + public static function associationEntityRequiredMissing(string $entity, string $missingEntity): self { return new AssociationEntityRequiredMissingException( @@ -290,6 +304,24 @@ public static function migrationIsAlreadyRunning(): self ); } + public static function checksumResetRunning(): self + { + return new MigrationIsAlreadyRunningException( + Response::HTTP_BAD_REQUEST, + self::MIGRATION_IS_RESETTING_CHECKSUMS, + 'Checksum reset is running.', + ); + } + + public static function truncatingDataRunning(): self + { + return new MigrationIsAlreadyRunningException( + Response::HTTP_BAD_REQUEST, + self::MIGRATION_IS_TRUNCATING_DATA, + 'Data truncation is running.', + ); + } + public static function noConnectionIsSelected(): self { return new self( @@ -499,4 +531,54 @@ public static function invalidWriteContext(Context $invalidContext): self ] ); } + + public static function failedToCreateMigrationLog(string $logClass): self + { + return new self( + Response::HTTP_INTERNAL_SERVER_ERROR, + self::FAILED_TO_CREATE_MIGRATION_LOG, + 'Failed to create migration log of class "{{ logClass }}".', + ['logClass' => $logClass] + ); + } + + public static function unexpectedNullValue(string $fieldName): self + { + return new self( + Response::HTTP_INTERNAL_SERVER_ERROR, + self::UNEXPECTED_NULL_VALUE, + 'Unexpected null value for field "{{ fieldName }}".', + ['fieldName' => $fieldName] + ); + } + + public static function couldNotConvertFix(string $missingKey): self + { + return new self( + Response::HTTP_INTERNAL_SERVER_ERROR, + self::MISSING_MIGRATION_FIX_KEY, + 'Missing key "{{ missingKey }}" to construct MigrationFix.', + ['missingKey' => $missingKey] + ); + } + + public static function migrationNotInStep(string $runUuid, string $step): self + { + return new NoRunningMigrationException( + Response::HTTP_BAD_REQUEST, + self::MIGRATION_NOT_IN_STEP, + 'Migration with id: "{{ runUuid }}" is not in step "{{ step }}".', + ['runUuid' => $runUuid, 'step' => $step] + ); + } + + public static function invalidId(string $entityId, string $entityName): self + { + return new self( + Response::HTTP_INTERNAL_SERVER_ERROR, + self::INVALID_ID, + 'The id "{{ entityId }}" for entity "{{ entityName }}" is not a valid Uuid', + ['entityId' => $entityId, 'entityName' => $entityName] + ); + } } diff --git a/src/Migration/Converter/Converter.php b/src/Migration/Converter/Converter.php index 5c4ee2cc2..4945a31ed 100644 --- a/src/Migration/Converter/Converter.php +++ b/src/Migration/Converter/Converter.php @@ -9,6 +9,7 @@ use Shopware\Core\Framework\Context; use Shopware\Core\Framework\Log\Package; +use Shopware\Core\Framework\Util\Hasher; use SwagMigrationAssistant\Migration\Logging\LoggingServiceInterface; use SwagMigrationAssistant\Migration\Mapping\MappingServiceInterface; use SwagMigrationAssistant\Migration\MigrationContextInterface; @@ -21,7 +22,7 @@ abstract class Converter implements ConverterInterface protected LoggingServiceInterface $loggingService; /** - * @var ?array{id: string, connectionId: string, oldIdentifier: ?string, entityUuid: ?string, entityValue: ?string, checksum: ?string, additionalData: ?array} + * @var ?array{id: string, connectionId: string, oldIdentifier: ?string, entityId: ?string, entityValue: ?string, checksum: ?string, additionalData: ?array} */ protected ?array $mainMapping = null; @@ -58,7 +59,7 @@ public function getMediaUuids(array $converted): ?array */ protected function generateChecksum(array $data): void { - $this->checksum = \md5(\serialize($data)); + $this->checksum = Hasher::hash(\serialize($data)); } /** @@ -70,13 +71,18 @@ protected function updateMainMapping(MigrationContextInterface $migrationContext return; } + if (!\is_array($this->mainMapping['additionalData'] ?? null)) { + $this->mainMapping['additionalData'] = []; + } + $this->mainMapping['checksum'] = $this->checksum; $this->mainMapping['additionalData']['relatedMappings'] = $this->mappingIds; $this->mappingIds = []; $dataSet = $migrationContext->getDataSet(); $connection = $migrationContext->getConnection(); - if ($dataSet === null || $connection === null) { + + if ($dataSet === null) { return; } diff --git a/src/Migration/Converter/ConverterInterface.php b/src/Migration/Converter/ConverterInterface.php index 1a83d4f89..6850b75bd 100644 --- a/src/Migration/Converter/ConverterInterface.php +++ b/src/Migration/Converter/ConverterInterface.php @@ -38,9 +38,11 @@ public function getMediaUuids(array $converted): ?array; /** * Converts the given data into the internal structure * + * A converter also could return null in various cases + * * @param array $data */ - public function convert(array $data, Context $context, MigrationContextInterface $migrationContext): ConvertStruct; + public function convert(array $data, Context $context, MigrationContextInterface $migrationContext): ?ConvertStruct; public function writeMapping(Context $context): void; } diff --git a/src/Migration/Converter/ConverterRegistry.php b/src/Migration/Converter/ConverterRegistry.php index 77a328830..86a11f66e 100644 --- a/src/Migration/Converter/ConverterRegistry.php +++ b/src/Migration/Converter/ConverterRegistry.php @@ -33,11 +33,6 @@ public function getConverter(MigrationContextInterface $migrationContext): Conve } } - $connection = $migrationContext->getConnection(); - if ($connection === null) { - throw MigrationException::migrationContextPropertyMissing('Connection'); - } - - throw MigrationException::converterNotFound($connection->getProfileName()); + throw MigrationException::converterNotFound($migrationContext->getProfile()->getName()); } } diff --git a/src/Migration/ErrorResolution/Entity/SwagMigrationFixCollection.php b/src/Migration/ErrorResolution/Entity/SwagMigrationFixCollection.php new file mode 100644 index 000000000..70b0f2fc3 --- /dev/null +++ b/src/Migration/ErrorResolution/Entity/SwagMigrationFixCollection.php @@ -0,0 +1,23 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Migration\ErrorResolution\Entity; + +use Shopware\Core\Framework\DataAbstractionLayer\EntityCollection; +use Shopware\Core\Framework\Log\Package; + +/** + * @extends EntityCollection + */ +#[Package('fundamentals@after-sales')] +class SwagMigrationFixCollection extends EntityCollection +{ + protected function getExpectedClass(): string + { + return SwagMigrationFixEntity::class; + } +} diff --git a/src/Migration/ErrorResolution/Entity/SwagMigrationFixDefinition.php b/src/Migration/ErrorResolution/Entity/SwagMigrationFixDefinition.php new file mode 100644 index 000000000..d0f2ff340 --- /dev/null +++ b/src/Migration/ErrorResolution/Entity/SwagMigrationFixDefinition.php @@ -0,0 +1,54 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Migration\ErrorResolution\Entity; + +use Shopware\Core\Framework\DataAbstractionLayer\EntityDefinition; +use Shopware\Core\Framework\DataAbstractionLayer\Field\CreatedAtField; +use Shopware\Core\Framework\DataAbstractionLayer\Field\Flag\PrimaryKey; +use Shopware\Core\Framework\DataAbstractionLayer\Field\Flag\Required; +use Shopware\Core\Framework\DataAbstractionLayer\Field\IdField; +use Shopware\Core\Framework\DataAbstractionLayer\Field\StringField; +use Shopware\Core\Framework\DataAbstractionLayer\Field\UpdatedAtField; +use Shopware\Core\Framework\DataAbstractionLayer\FieldCollection; +use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Core\Field\AnyJsonField; + +#[Package('fundamentals@after-sales')] +class SwagMigrationFixDefinition extends EntityDefinition +{ + public const ENTITY_NAME = 'swag_migration_fix'; + + public function getEntityName(): string + { + return self::ENTITY_NAME; + } + + public function getCollectionClass(): string + { + return SwagMigrationFixCollection::class; + } + + public function getEntityClass(): string + { + return SwagMigrationFixEntity::class; + } + + protected function defineFields(): FieldCollection + { + return new FieldCollection([ + (new IdField('id', 'id'))->addFlags(new PrimaryKey(), new Required()), + (new IdField('connection_id', 'connectionId'))->addFlags(new Required()), + (new AnyJsonField('value', 'value'))->addFlags(new Required()), + (new StringField('path', 'path'))->addFlags(new Required()), + new IdField('entity_id', 'entityId'), + new StringField('entity_name', 'entityName'), + new CreatedAtField(), + new UpdatedAtField(), + ]); + } +} diff --git a/src/Migration/ErrorResolution/Entity/SwagMigrationFixEntity.php b/src/Migration/ErrorResolution/Entity/SwagMigrationFixEntity.php new file mode 100644 index 000000000..71b3e991c --- /dev/null +++ b/src/Migration/ErrorResolution/Entity/SwagMigrationFixEntity.php @@ -0,0 +1,78 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Migration\ErrorResolution\Entity; + +use Shopware\Core\Framework\DataAbstractionLayer\Entity; +use Shopware\Core\Framework\DataAbstractionLayer\EntityIdTrait; +use Shopware\Core\Framework\Log\Package; + +#[Package('fundamentals@after-sales')] +class SwagMigrationFixEntity extends Entity +{ + use EntityIdTrait; + + protected string $connectionId; + + protected mixed $value; + + protected string $path; + + protected string $entityId; + + protected string $entityName; + + public function getConnectionId(): string + { + return $this->connectionId; + } + + public function setConnectionId(string $connectionId): void + { + $this->connectionId = $connectionId; + } + + public function getValue(): mixed + { + return $this->value; + } + + public function setValue(mixed $value): void + { + $this->value = $value; + } + + public function getPath(): string + { + return $this->path; + } + + public function setPath(string $path): void + { + $this->path = $path; + } + + public function getEntityId(): string + { + return $this->entityId; + } + + public function setEntityId(string $entityId): void + { + $this->entityId = $entityId; + } + + public function getEntityName(): string + { + return $this->entityName; + } + + public function setEntityName(string $entityName): void + { + $this->entityName = $entityName; + } +} diff --git a/src/Migration/ErrorResolution/MigrationErrorResolutionService.php b/src/Migration/ErrorResolution/MigrationErrorResolutionService.php new file mode 100644 index 000000000..b066b78bf --- /dev/null +++ b/src/Migration/ErrorResolution/MigrationErrorResolutionService.php @@ -0,0 +1,89 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Migration\ErrorResolution; + +use Doctrine\DBAL\ArrayParameterType; +use Doctrine\DBAL\Connection; +use Shopware\Core\Framework\Log\Package; +use Shopware\Core\Framework\Uuid\Uuid; + +#[Package('fundamentals@after-sales')] +class MigrationErrorResolutionService +{ + public function __construct( + private readonly Connection $connection, + ) { + } + + /** + * @param array> $data + */ + public function applyFixes(array &$data, string $connectionId, string $runId): void + { + $itemIds = \array_column($data, 'id'); + $fixes = $this->getFixes($itemIds, $connectionId, $runId); + + foreach ($data as &$item) { + $id = $item['id']; + + if (!\array_key_exists($id, $fixes) || !\is_array($fixes[$id])) { + continue; + } + + foreach ($fixes[$id] as $fix) { + $fix->apply($item); + } + } + + unset($item); + } + + /** + * @param array $ids + * + * @return array> + */ + private function getFixes(array $ids, string $connectionId, string $runId): array + { + // To ensure, only select fixes for the current run, join swag_migration_logging table and filter by run_id + $sql = <<<'SQL' +SELECT fix.entity_id AS entityId, fix.id, fix.value, fix.path +FROM swag_migration_fix AS fix +INNER JOIN swag_migration_logging AS log ON log.entity_id = fix.entity_id +WHERE fix.entity_id IN (:ids) +AND fix.connection_id = :connectionId +AND log.run_id = :runId +AND log.user_fixable = 1; +SQL; + + $result = $this->connection->fetchAllAssociative( + $sql, + [ + 'ids' => Uuid::fromHexToBytesList($ids), + 'connectionId' => Uuid::fromHexToBytes($connectionId), + 'runId' => Uuid::fromHexToBytes($runId), + ], + [ + 'ids' => ArrayParameterType::STRING, + ] + ); + + $return = []; + foreach ($result as $row) { + $entityId = Uuid::fromBytesToHex($row['entityId']); + + if (!\array_key_exists($entityId, $return)) { + $return[$entityId] = []; + } + + $return[$entityId][] = MigrationFix::fromDatabaseQuery($row); + } + + return $return; + } +} diff --git a/src/Migration/ErrorResolution/MigrationFix.php b/src/Migration/ErrorResolution/MigrationFix.php new file mode 100644 index 000000000..1707531e2 --- /dev/null +++ b/src/Migration/ErrorResolution/MigrationFix.php @@ -0,0 +1,84 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Migration\ErrorResolution; + +use Shopware\Core\Framework\Log\Package; +use Shopware\Core\Framework\Uuid\Uuid; +use SwagMigrationAssistant\Exception\MigrationException; + +#[Package('fundamentals@after-sales')] +class MigrationFix +{ + private const PATH_SEPARATOR = '.'; + + public function __construct( + public readonly string $id, + public readonly string $value, + public readonly string $path, + ) { + } + + /** + * @param array $data + */ + public static function fromDatabaseQuery(array $data): self + { + $expectedArrayKeys = ['id', 'value', 'path']; + foreach ($expectedArrayKeys as $expectedKey) { + if (!\array_key_exists($expectedKey, $data)) { + throw MigrationException::couldNotConvertFix($expectedKey); + } + } + + return new self( + Uuid::fromBytesToHex($data['id']), + $data['value'], + $data['path'], + ); + } + + /** + * @param array $item + */ + public function apply(array &$item): void + { + /* + * Explode the path to an array + * Path example: 'category.language.name' + * Results in an array like: ['category', 'language', 'name'] + */ + $pathArray = explode(self::PATH_SEPARATOR, $this->path); + + /* + * Set current item as pointer + * Item structure for example has no valid value for name and looks like: + * [ + * 'someOtherKeys', + * ... + * category => [ + * ... + * 'language' => [ + * ... + * 'name' => null, + * ] + * ] + * ] + */ + $nestedPointer = &$item; + + // Iterating over the path to follow them and set the nested pointer to the last key in pathArray + // In this example the result pointer is: $item['category']['language']['name'] + foreach ($pathArray as $key) { + $nestedPointer = &$nestedPointer[$key]; + } + + // Now set the value to the pointer like: $item['category']['language']['name'] = 'new Value' + $nestedPointer = \json_decode($this->value, true, 512, \JSON_THROW_ON_ERROR); + unset($nestedPointer); + } +} diff --git a/src/Migration/Gateway/GatewayInterface.php b/src/Migration/Gateway/GatewayInterface.php index ff489dd40..f875cb65f 100644 --- a/src/Migration/Gateway/GatewayInterface.php +++ b/src/Migration/Gateway/GatewayInterface.php @@ -11,6 +11,7 @@ use Shopware\Core\Framework\Log\Package; use SwagMigrationAssistant\Migration\EnvironmentInformation; use SwagMigrationAssistant\Migration\MigrationContextInterface; +use SwagMigrationAssistant\Migration\Profile\ProfileInterface; use SwagMigrationAssistant\Migration\TotalStruct; #[Package('fundamentals@after-sales')] @@ -23,7 +24,7 @@ public function getSnippetName(): string; /** * Identifier for a gateway registry */ - public function supports(MigrationContextInterface $migrationContext): bool; + public function supports(ProfileInterface $profile): bool; /** * Reads the given entity type from via context from its connection and returns the data diff --git a/src/Migration/Gateway/GatewayRegistry.php b/src/Migration/Gateway/GatewayRegistry.php index 7ba39d663..564ad34c6 100644 --- a/src/Migration/Gateway/GatewayRegistry.php +++ b/src/Migration/Gateway/GatewayRegistry.php @@ -26,9 +26,11 @@ public function __construct(private readonly iterable $gateways) */ public function getGateways(MigrationContextInterface $migrationContext): array { + $profile = $migrationContext->getProfile(); + $gateways = []; foreach ($this->gateways as $gateway) { - if ($gateway->supports($migrationContext)) { + if ($gateway->supports($profile)) { $gateways[] = $gateway; } } @@ -39,15 +41,11 @@ public function getGateways(MigrationContextInterface $migrationContext): array public function getGateway(MigrationContextInterface $migrationContext): GatewayInterface { $connection = $migrationContext->getConnection(); - if ($connection === null) { - throw MigrationException::migrationContextPropertyMissing('Connection'); - } - $profileName = $connection->getProfileName(); $gatewayName = $connection->getGatewayName(); foreach ($this->gateways as $gateway) { - if ($gateway->supports($migrationContext) && $gateway->getName() === $gatewayName) { + if ($gateway->supports($migrationContext->getProfile()) && $gateway->getName() === $gatewayName) { return $gateway; } } diff --git a/src/Migration/History/HistoryService.php b/src/Migration/History/HistoryService.php index 573d36542..7c9dd7116 100644 --- a/src/Migration/History/HistoryService.php +++ b/src/Migration/History/HistoryService.php @@ -31,8 +31,8 @@ #[Package('fundamentals@after-sales')] class HistoryService implements HistoryServiceInterface { - private const LOG_FETCH_LIMIT = 50; - private const LOG_TIME_FORMAT = 'd.m.Y h:i:s e'; + public const LOG_FETCH_LIMIT = 50; + public const LOG_TIME_FORMAT = 'Y-m-d H:i:s T'; /** * @param EntityRepository $runRepo @@ -59,25 +59,14 @@ public function getGroupedLogsOfRun( null, null, new TermsAggregation( - 'titleSnippet', - 'titleSnippet', - null, - null, - new TermsAggregation( - 'entity', - 'entity', - null, - null, - new TermsAggregation( - 'level', - 'level' - ) - ) + 'level', + 'level' ) ) ); $result = $this->loggingRepo->aggregate($criteria, $context); + /** @var TermsResult $termsResult */ $termsResult = $result->get('count'); $aggregateResult = $termsResult->getBuckets(); @@ -87,6 +76,7 @@ public function getGroupedLogsOfRun( } $cleanResult = []; + foreach ($aggregateResult as $bucket) { $detailInformation = $this->extractBucketInformation($bucket); $cleanResult[] = $detailInformation; @@ -100,30 +90,39 @@ public function getGroupedLogsOfRun( */ public function downloadLogsOfRun(string $runUuid, Context $context): \Closure { - $offset = 0; - $total = $this->getTotalLogCount($runUuid, $context); $run = $this->getMigrationRun($runUuid, $context); - return function () use ($run, $runUuid, $offset, $total, $context): void { - if ($run !== null) { - \printf('%s%s', $this->getPrefixLogInformation($run), \PHP_EOL); + if ($run === null) { + throw MigrationException::entityNotExists( + SwagMigrationRunEntity::class, + $runUuid + ); + } + + $total = $this->getTotalLogCount($runUuid, $context); + + return function () use ($run, $runUuid, $total, $context): void { + $offset = 0; + + \printf('%s', $this->getPrefixLogInformation($run)); + + if ($total === 0) { + \printf('%sNo log entries found for this migration run.%s', \PHP_EOL, \PHP_EOL); } while ($offset < $total) { $logChunk = $this->getLogChunk($runUuid, $offset, $context); foreach ($logChunk->getElements() as $logEntry) { - \printf('[%s] %s%s', $logEntry->getLevel(), $logEntry->getCode(), \PHP_EOL); - \printf('%s%s', $logEntry->getTitle(), \PHP_EOL); - \printf('%s%s%s', $logEntry->getDescription(), \PHP_EOL, \PHP_EOL); + if (!$logEntry instanceof SwagMigrationLoggingEntity) { + continue; + } + + $this->printLogEntry($logEntry); } $offset += self::LOG_FETCH_LIMIT; } - - if ($run !== null) { - \printf('%s%s%s', $this->getSuffixLogInformation($run), \PHP_EOL, \PHP_EOL); - } }; } @@ -151,31 +150,67 @@ public function isMediaProcessing(): bool 'SELECT COUNT(id) FROM swag_migration_media_file WHERE processed = 0 and process_failure != 1' )->fetchOne(); - return $unprocessedCount !== '0'; + return (int) $unprocessedCount !== 0; } - private function extractBucketInformation(Bucket $bucket): array + private function printLogEntry(SwagMigrationLoggingEntity $logEntry): void { - /** @var TermsResult $titleResult */ - $titleResult = $bucket->getResult(); - $titleBucket = $titleResult->getBuckets()[0]; + \printf('----- Log Entry #%d -----%s', $logEntry->getAutoIncrement(), \PHP_EOL); + \printf('ID: %s%s', $logEntry->getId(), \PHP_EOL); + \printf('Level: %s%s', $logEntry->getLevel(), \PHP_EOL); + \printf('Code: %s%s', $logEntry->getCode(), \PHP_EOL); + \printf('Profile name: %s%s', $logEntry->getProfileName(), \PHP_EOL); + \printf('Gateway name: %s%s', $logEntry->getGatewayName(), \PHP_EOL); + \printf('Created at: %s%s', $logEntry->getCreatedAt()?->format(self::LOG_TIME_FORMAT) ?? '-', \PHP_EOL); + + if ($logEntry->getEntityName()) { + \printf('Entity: %s%s', $logEntry->getEntityName(), \PHP_EOL); + } - /** @var TermsResult $entityResult */ - $entityResult = $titleBucket->getResult(); - $entityString = empty($entityResult->getBuckets()) ? '' : $entityResult->getBuckets()[0]->getKey(); + if ($logEntry->getFieldName()) { + \printf('Field: %s%s', $logEntry->getFieldName(), \PHP_EOL); + } + + if ($logEntry->getFieldSourcePath()) { + \printf('Source path: %s%s', $logEntry->getFieldSourcePath(), \PHP_EOL); + } + + if ($logEntry->getExceptionMessage()) { + \printf('Exception message: %s%s', $logEntry->getExceptionMessage(), \PHP_EOL); + } + + if ($logEntry->getSourceData()) { + \printf('Source data (JSON):%s%s%s', \PHP_EOL, \json_encode($logEntry->getSourceData(), \JSON_PRETTY_PRINT) ?: '{}', \PHP_EOL); + } + if ($logEntry->getConvertedData()) { + \printf('Converted data (JSON):%s%s%s', \PHP_EOL, \json_encode($logEntry->getConvertedData(), \JSON_PRETTY_PRINT) ?: '{}', \PHP_EOL); + } + + if ($logEntry->getExceptionTrace()) { + \printf('Exception trace (JSON):%s%s%s', \PHP_EOL, \json_encode($logEntry->getExceptionTrace(), \JSON_PRETTY_PRINT) ?: '{}', \PHP_EOL); + } + + \printf(\PHP_EOL); + } + + private function extractBucketInformation(Bucket $bucket): array + { + /** @var TermsResult|null $levelResult */ + $levelResult = $bucket->getResult(); $levelString = ''; - if ($entityString !== '') { - /** @var TermsResult $levelResult */ - $levelResult = $entityResult->getBuckets()[0]->getResult(); - $levelString = empty($levelResult->getBuckets()) ? '' : $levelResult->getBuckets()[0]->getKey(); + + if ($levelResult !== null) { + $levelBuckets = $levelResult->getBuckets(); + + if (!empty($levelBuckets)) { + $levelString = $levelBuckets[0]->getKey(); + } } return [ 'code' => $bucket->getKey(), 'count' => $bucket->getCount(), - 'titleSnippet' => $titleBucket->getKey(), - 'entity' => $entityString, 'level' => $levelString, ]; } @@ -187,6 +222,7 @@ private function getTotalLogCount(string $runUuid, Context $context): int $criteria->addAggregation(new CountAggregation('count', 'id')); $result = $this->loggingRepo->aggregate($criteria, $context); + /** @var CountResult $countResult */ $countResult = $result->get('count'); @@ -208,6 +244,7 @@ private function getLogChunk(string $runUuid, int $offset, Context $context): En { $criteria = new Criteria(); $criteria->addFilter(new EqualsFilter('runId', $runUuid)); + $criteria->addFilter(new EqualsFilter('userFixable', 0)); $criteria->addSorting(new FieldSorting('autoIncrement', FieldSorting::ASCENDING)); $criteria->setOffset($offset); $criteria->setLimit(self::LOG_FETCH_LIMIT); @@ -221,38 +258,38 @@ private function getPrefixLogInformation(SwagMigrationRunEntity $run): string $profileName = '-'; $gatewayName = '-'; $connectionName = '-'; + + $premapping = 'Associated connection not found'; + if ($connection !== null) { $connectionName = $connection->getName(); $profileName = $connection->getProfileName(); $gatewayName = $connection->getGatewayName(); + $premapping = $connection->getPremapping(); } - $updatedAt = $run->getUpdatedAt(); - if ($updatedAt !== null) { - $updatedAt = $updatedAt->format(self::LOG_TIME_FORMAT); - } else { - $updatedAt = '-'; - } - - $createdAt = $run->getCreatedAt(); - if ($createdAt !== null) { - $createdAt = $createdAt->format(self::LOG_TIME_FORMAT); - } else { - $createdAt = '-'; - } + $updatedAt = $run->getUpdatedAt()?->format(self::LOG_TIME_FORMAT) ?? '-'; + $createdAt = $run->getCreatedAt()?->format(self::LOG_TIME_FORMAT) ?? '-'; return \sprintf( - 'Migration log generated at %s' . \PHP_EOL - . 'Run id: %s' . \PHP_EOL + '########## MIGRATION LOG ##########' . \PHP_EOL . \PHP_EOL + . '########## RUN INFORMATION ##########' . \PHP_EOL + . 'Generated at: %s' . \PHP_EOL + . 'Run ID: %s' . \PHP_EOL . 'Status: %s' . \PHP_EOL . 'Created at: %s' . \PHP_EOL - . 'Updated at: %s' . \PHP_EOL - . 'Connection id: %s' . \PHP_EOL + . 'Updated at: %s' . \PHP_EOL . \PHP_EOL + . '########## CONNECTION INFORMATION ##########' . \PHP_EOL + . 'Connection ID: %s' . \PHP_EOL . 'Connection name: %s' . \PHP_EOL - . 'Profile: %s' . \PHP_EOL - . 'Gateway: %s' . \PHP_EOL . \PHP_EOL - . 'Selected dataSets:' . \PHP_EOL . '%s' . \PHP_EOL - . '--------------------Log-entries---------------------' . \PHP_EOL, + . 'Profile name: %s' . \PHP_EOL + . 'Gateway name: %s' . \PHP_EOL . \PHP_EOL + . '########## SELECTED DATASETS ##########' . \PHP_EOL + . '%s' . \PHP_EOL + . '########## ADDITIONAL METADATA ##########' . \PHP_EOL + . 'Environment information (JSON):' . \PHP_EOL . '%s' . \PHP_EOL . \PHP_EOL + . 'Pre-mapping (JSON):' . \PHP_EOL . '%s' . \PHP_EOL . \PHP_EOL + . '########## LOG ENTRIES ##########' . \PHP_EOL, \date(self::LOG_TIME_FORMAT), $run->getId(), $run->getStepValue(), @@ -262,38 +299,24 @@ private function getPrefixLogInformation(SwagMigrationRunEntity $run): string $connectionName, $profileName, $gatewayName, - $this->getFormattedSelectedDataSets($run->getProgress()) + $this->getFormattedSelectedDataSets($run->getProgress()), + \json_encode($run->getEnvironmentInformation(), \JSON_PRETTY_PRINT), + \json_encode($premapping, \JSON_PRETTY_PRINT) ); } private function getFormattedSelectedDataSets(?MigrationProgress $progress): string { if ($progress === null || $progress->getDataSets()->count() < 1) { - return ''; + return 'No datasets selected.' . \PHP_EOL; } $output = ''; + foreach ($progress->getDataSets() as $dataSet) { - $output .= \sprintf('- %s (total: %d)' . \PHP_EOL, $dataSet->getEntityName(), $dataSet->getTotal()); + $output .= \sprintf('- %s (Total: %d)' . \PHP_EOL, $dataSet->getEntityName(), $dataSet->getTotal()); } return $output; } - - private function getSuffixLogInformation(SwagMigrationRunEntity $run): string - { - $connection = $run->getConnection(); - $premapping = 'Associated connection not found'; - if ($connection !== null) { - $premapping = $connection->getPremapping(); - } - - return \sprintf( - '--------------------Additional-metadata---------------------' . \PHP_EOL - . 'Environment information {JSON}:' . \PHP_EOL . '%s' . \PHP_EOL . \PHP_EOL - . 'Premapping {JSON}: ----------------------------------------------------' . \PHP_EOL . '%s' . \PHP_EOL, - \json_encode($run->getEnvironmentInformation(), \JSON_PRETTY_PRINT), - \json_encode($premapping, \JSON_PRETTY_PRINT) - ); - } } diff --git a/src/Migration/History/LogGroupingService.php b/src/Migration/History/LogGroupingService.php new file mode 100644 index 000000000..eb3a15fb5 --- /dev/null +++ b/src/Migration/History/LogGroupingService.php @@ -0,0 +1,440 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Migration\History; + +use Doctrine\DBAL\Connection; +use Doctrine\DBAL\Exception; +use Doctrine\DBAL\ParameterType; +use Shopware\Core\Framework\Log\Package; +use Shopware\Core\Framework\Uuid\Uuid; +use SwagMigrationAssistant\Exception\MigrationException; + +/** + * @internal + * + * @SECURITY-NOTICE + * + * This service builds dynamic SQL queries with string interpolation for performance reasons. + * While this looks dangerous, it is SAFE because: + * + * 1. All user-controllable values that get interpolated into SQL (sortBy, sortDirection, filterStatus) + * are validated against explicit allowlists BEFORE being used in query construction. + * See: ALLOWED_SORT_COLUMNS, ALLOWED_SORT_DIRECTIONS, ALLOWED_FILTER_STATUSES constants. + * + * 2. All data values (runId, connectionId, filterCode, filterEntity, filterField) are passed + * as bound parameters (:paramName), never interpolated into SQL strings. + * + * The validation is centralized at the top of getGroupedLogsByCodeAndEntity() to make + * security review straightforward. Do not scatter validation logic across multiple methods. + */ +#[Package('fundamentals@after-sales')] +class LogGroupingService implements LogGroupingServiceInterface +{ + /** + * allowlist of columns that can be used for ORDER BY. + * keys are API parameter names, values are actual SQL column references. + * + * @SECURITY only these exact values can be interpolated into ORDER BY clauses. + */ + private const ALLOWED_SORT_COLUMNS = [ + 'count' => 'count', + 'code' => 'l.code', + 'entityName' => 'l.entity_name', + 'fieldName' => 'l.field_name', + 'profileName' => 'l.profile_name', + 'gatewayName' => 'l.gateway_name', + ]; + + /** + * allowlist of valid sort directions. + * + * @SECURITY only these exact values can be interpolated into ORDER BY clauses. + */ + private const ALLOWED_SORT_DIRECTIONS = ['ASC', 'DESC']; + + /** + * allowlist of valid filter status values. + * + * @SECURITY only these exact values can trigger HAVING clause generation. + */ + private const ALLOWED_FILTER_STATUSES = ['resolved', 'unresolved']; + + public function __construct( + private readonly Connection $connection, + ) { + } + + /** + * @throws Exception + * + * @return array{total: int, items: array, levelCounts: array{error: int, warning: int, info: int}} + */ + public function getGroupedLogsByCodeAndEntity( + string $runUuid, + string $level, + int $page, + int $limit, + string $sortBy, + string $sortDirection, + ?string $filterCode, + ?string $filterStatus, + ?string $filterEntity, + ?string $filterField, + ): array { + /** @SECURITY validates all values that will be interpolated into SQL - do not skip this step. */ + $orderColumn = $this->validateSortColumn($sortBy); + $orderDirection = $this->validateSortDirection($sortDirection); + $validatedFilterStatus = $this->validateFilterStatus($filterStatus); + + $runIdBytes = Uuid::fromHexToBytes($runUuid); + $connectionIdBytes = $this->getConnectionIdForRun($runIdBytes); + + $params = [ + 'runId' => $runIdBytes, + 'level' => $level, + 'limit' => $limit, + 'offset' => ($page - 1) * $limit, + 'connectionId' => $connectionIdBytes, + ]; + + // build optional WHERE conditions + $whereConditions = []; + + if ($filterCode !== null) { + $whereConditions[] = 'l.code = :filterCode'; + $params['filterCode'] = $filterCode; + } + + if ($filterEntity !== null) { + $whereConditions[] = 'l.entity_name = :filterEntity'; + $params['filterEntity'] = $filterEntity; + } + + if ($filterField !== null) { + $whereConditions[] = 'l.field_name = :filterField'; + $params['filterField'] = $filterField; + } + + $additionalWhere = $whereConditions !== [] ? ' AND ' . \implode(' AND ', $whereConditions) : ''; + + // determine if we need the fix join for status filtering + $includeFixJoin = $validatedFilterStatus !== null; + + $sql = $this->buildMainQuery( + $additionalWhere, + $validatedFilterStatus, + $orderColumn, + $orderDirection, + $includeFixJoin + ); + + $result = $this->connection->executeQuery($sql, $params, [ + 'limit' => ParameterType::INTEGER, + 'offset' => ParameterType::INTEGER, + ]); + + $rows = $result->fetchAllAssociative(); + $total = $rows !== [] ? (int) $rows[0]['total'] : 0; + + $levelCounts = $this->getLogLevelCounts( + $params, + $additionalWhere, + $validatedFilterStatus, + $includeFixJoin + ); + + return [ + 'total' => $total, + 'items' => $this->mapLogsFromRows($rows), + 'levelCounts' => $levelCounts, + ]; + } + + /** + * @throws Exception + * + * @return array + */ + public function getAllLogIdsByCodeAndEntity( + string $runId, + string $code, + string $entityName, + string $fieldName, + ?string $connectionId = null, + ): array { + $params = [ + 'runId' => Uuid::fromHexToBytes($runId), + 'code' => $code, + 'entityName' => $entityName, + 'fieldName' => $fieldName, + ]; + + // this is safe, it's a static string, not user input + $connectionJoinCondition = ''; + + if ($connectionId !== null && $connectionId !== '') { + $connectionJoinCondition = ' AND f.connection_id = :connectionId'; + $params['connectionId'] = Uuid::fromHexToBytes($connectionId); + } + + $sql = " + SELECT LOWER(HEX(l.id)) as id + FROM swag_migration_logging l + LEFT JOIN swag_migration_fix f ON ( + f.entity_name = l.entity_name + AND f.path = l.field_name + AND f.entity_id = l.entity_id + {$connectionJoinCondition} + ) + WHERE l.run_id = :runId + AND l.code = :code + AND l.entity_name = :entityName + AND l.field_name = :fieldName + AND l.user_fixable = 1 + AND f.id IS NULL + "; + + $result = $this->connection->executeQuery($sql, $params); + + return \array_column($result->fetchAllAssociative(), 'id'); + } + + /** + * validates sortBy parameter against allowlist and returns the SQL column name. + * returns 'count' as default if input is not in ALLOWED_SORT_COLUMNS. + */ + private function validateSortColumn(string $sortBy): string + { + return self::ALLOWED_SORT_COLUMNS[$sortBy] ?? 'count'; + } + + /** + * validates sortDirection parameter against allowlist. + * returns 'DESC' as default if input is not in ALLOWED_SORT_DIRECTIONS. + */ + private function validateSortDirection(string $sortDirection): string + { + $normalized = \strtoupper($sortDirection); + + return \in_array($normalized, self::ALLOWED_SORT_DIRECTIONS, true) ? $normalized : 'DESC'; + } + + /** + * validates filterStatus parameter against allowlist. + * returns null if input is not in ALLOWED_FILTER_STATUSES. + */ + private function validateFilterStatus(?string $filterStatus): ?string + { + if ($filterStatus === null) { + return null; + } + + return \in_array($filterStatus, self::ALLOWED_FILTER_STATUSES, true) ? $filterStatus : null; + } + + /** + * builds the main grouped logs query. + */ + private function buildMainQuery( + string $additionalWhere, + ?string $filterStatus, + string $orderColumn, + string $orderDirection, + bool $includeFixJoin, + ): string { + // build HAVING clause from validated filter status + $havingClause = match ($filterStatus) { + 'resolved' => 'HAVING COUNT(DISTINCT l.id) > 0 AND COUNT(DISTINCT l.id) = COUNT(DISTINCT f.id)', + 'unresolved' => 'HAVING COUNT(DISTINCT l.id) > 0 AND COUNT(DISTINCT l.id) != COUNT(DISTINCT f.id)', + default => '', + }; + + // build count subquery components + $countSubqueryFixJoin = $includeFixJoin + ? 'LEFT JOIN swag_migration_fix f2 ON ( + f2.connection_id = :connectionId + AND f2.entity_name = l2.entity_name + AND f2.path = l2.field_name + AND f2.entity_id = l2.entity_id + )' + : ''; + + $countSubqueryHaving = match ($filterStatus) { + 'resolved' => 'HAVING COUNT(DISTINCT l2.id) > 0 AND COUNT(DISTINCT l2.id) = COUNT(DISTINCT f2.id)', + 'unresolved' => 'HAVING COUNT(DISTINCT l2.id) > 0 AND COUNT(DISTINCT l2.id) != COUNT(DISTINCT f2.id)', + default => '', + }; + + $countSubqueryWhere = \str_replace('l.', 'l2.', $additionalWhere); + + /* + * MAIN QUERY STRUCTURE: + * this query groups logs by code, entity_name, and field_name, counting occurrences + * and tracking fix status. The subquery calculates total count for pagination. + */ + return " + SELECT + l.code, + l.entity_name, + l.field_name, + l.gateway_name, + l.profile_name, + COUNT(DISTINCT l.id) as count, + ( + SELECT COUNT(*) + FROM ( + SELECT 1 + FROM swag_migration_logging l2 + {$countSubqueryFixJoin} + WHERE l2.run_id = :runId + AND l2.level = :level + AND l2.user_fixable = 1 + {$countSubqueryWhere} + GROUP BY l2.code, l2.entity_name, l2.field_name + {$countSubqueryHaving} + ) as grouped_logs + ) as total, + COUNT(DISTINCT f.id) as fix_count + FROM swag_migration_logging l + LEFT JOIN swag_migration_fix f ON ( + f.connection_id = :connectionId + AND f.entity_name = l.entity_name + AND f.path = l.field_name + AND f.entity_id = l.entity_id + ) + WHERE l.run_id = :runId + AND l.level = :level + AND l.user_fixable = 1 + {$additionalWhere} + GROUP BY l.code, l.entity_name, l.field_name + {$havingClause} + ORDER BY {$orderColumn} {$orderDirection}, l.code ASC, l.entity_name ASC, l.field_name ASC + LIMIT :limit OFFSET :offset + "; + } + + /** + * gets log counts grouped by level for the filter badge counts. + * + * @param array $params + * + * @throws Exception + * + * @return array{error: int, warning: int, info: int} + */ + private function getLogLevelCounts( + array $params, + string $additionalWhere, + ?string $filterStatus, + bool $includeFixJoin, + ): array { + $joinClause = $includeFixJoin + ? 'LEFT JOIN swag_migration_fix f ON ( + f.connection_id = :connectionId + AND f.entity_name = l.entity_name + AND f.path = l.field_name + AND f.entity_id = l.entity_id + )' + : ''; + + $havingClause = $includeFixJoin + ? match ($filterStatus) { + 'resolved' => 'HAVING COUNT(DISTINCT l.id) > 0 AND COUNT(DISTINCT l.id) = COUNT(DISTINCT f.id)', + 'unresolved' => 'HAVING COUNT(DISTINCT l.id) > 0 AND COUNT(DISTINCT l.id) != COUNT(DISTINCT f.id)', + default => '', + } + : ''; + + $sql = " + SELECT + level, + COUNT(DISTINCT CONCAT(code, '|', COALESCE(entity_name, ''), '|', COALESCE(field_name, ''))) as count + FROM ( + SELECT + l.level, + l.code, + l.entity_name, + l.field_name + FROM swag_migration_logging l + {$joinClause} + WHERE l.run_id = :runId + AND l.user_fixable = 1 + {$additionalWhere} + GROUP BY l.level, l.code, l.entity_name, l.field_name + {$havingClause} + ) as filtered_logs + GROUP BY level + "; + + $result = $this->connection->executeQuery($sql, $params); + + return $this->mapLevelCountsFromRows($result->fetchAllAssociative()); + } + + /** + * @throws Exception + */ + private function getConnectionIdForRun(string $runIdBytes): string + { + $result = $this->connection->fetchOne( + 'SELECT connection_id FROM swag_migration_run WHERE id = :runId', + ['runId' => $runIdBytes] + ); + + if ($result === false) { + throw MigrationException::noConnectionFound(); + } + + return $result; + } + + /** + * @param array> $rows + * + * @return array + */ + private function mapLogsFromRows(array $rows): array + { + return \array_map( + static fn (array $row) => [ + 'code' => $row['code'], + 'entityName' => $row['entity_name'], + 'fieldName' => $row['field_name'], + 'profileName' => $row['profile_name'], + 'gatewayName' => $row['gateway_name'], + 'count' => (int) $row['count'], + 'fixCount' => (int) $row['fix_count'], + ], + $rows + ); + } + + /** + * @param array> $rows + * + * @return array{error: int, warning: int, info: int} + */ + private function mapLevelCountsFromRows(array $rows): array + { + $counts = [ + 'error' => 0, + 'warning' => 0, + 'info' => 0, + ]; + + foreach ($rows as $row) { + $level = \strtolower($row['level']); + + if (isset($counts[$level])) { + $counts[$level] = (int) $row['count']; + } + } + + return $counts; + } +} diff --git a/src/Migration/History/LogGroupingServiceInterface.php b/src/Migration/History/LogGroupingServiceInterface.php new file mode 100644 index 000000000..6cb44fe69 --- /dev/null +++ b/src/Migration/History/LogGroupingServiceInterface.php @@ -0,0 +1,44 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Migration\History; + +use Shopware\Core\Framework\Log\Package; + +/** + * @internal + */ +#[Package('fundamentals@after-sales')] +interface LogGroupingServiceInterface +{ + /** + * @return array{total: int, items: array, levelCounts: array{error: int, warning: int, info: int}} + */ + public function getGroupedLogsByCodeAndEntity( + string $runUuid, + string $level, + int $page, + int $limit, + string $sortBy, + string $sortDirection, + ?string $filterCode, + ?string $filterStatus, + ?string $filterEntity, + ?string $filterField, + ): array; + + /** + * @return array + */ + public function getAllLogIdsByCodeAndEntity( + string $runId, + string $code, + string $entityName, + string $fieldName, + ?string $connectionId = null, + ): array; +} diff --git a/src/Migration/Logging/Log/AssociationRequiredMissingLog.php b/src/Migration/Logging/Log/AssociationRequiredMissingLog.php index 6e9ade2ca..608c5961f 100644 --- a/src/Migration/Logging/Log/AssociationRequiredMissingLog.php +++ b/src/Migration/Logging/Log/AssociationRequiredMissingLog.php @@ -8,17 +8,14 @@ namespace SwagMigrationAssistant\Migration\Logging\Log; use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; #[Package('fundamentals@after-sales')] -class AssociationRequiredMissingLog extends BaseRunLogEntry +readonly class AssociationRequiredMissingLog extends AbstractMigrationLogEntry { - public function __construct( - string $runId, - string $entity, - string $sourceId, - private readonly string $requiredFor, - ) { - parent::__construct($runId, $entity, $sourceId); + public function isUserFixable(): bool + { + return false; } public function getLevel(): string @@ -28,55 +25,6 @@ public function getLevel(): string public function getCode(): string { - $entity = $this->getEntity(); - if ($entity === null) { - return 'SWAG_MIGRATION__SHOPWARE_ASSOCIATION_REQUIRED_MISSING'; - } - - return \sprintf('SWAG_MIGRATION__SHOPWARE_ASSOCIATION_REQUIRED_MISSING_%s', \mb_strtoupper($entity)); - } - - public function getTitle(): string - { - $entity = $this->getEntity(); - if ($entity === null) { - return 'Associated not found'; - } - - return \sprintf('Associated %s not found', $entity); - } - - /** - * @return array{missingEntity: ?string, requiredFor: string, sourceId: ?string} - */ - public function getParameters(): array - { - return [ - 'missingEntity' => $this->getEntity(), - 'requiredFor' => $this->requiredFor, - 'sourceId' => $this->getSourceId(), - ]; - } - - public function getDescription(): string - { - $args = $this->getParameters(); - - return \sprintf( - 'The %s with the source id "%s" can not be found but is required for %s.', - $args['missingEntity'], - $args['sourceId'], - $args['requiredFor'] - ); - } - - public function getTitleSnippet(): string - { - return \sprintf('%s.%s.title', $this->getSnippetRoot(), 'SWAG_MIGRATION__SHOPWARE_ASSOCIATION_REQUIRED_MISSING'); - } - - public function getDescriptionSnippet(): string - { - return \sprintf('%s.%s.description', $this->getSnippetRoot(), 'SWAG_MIGRATION__SHOPWARE_ASSOCIATION_REQUIRED_MISSING'); + return 'SWAG_MIGRATION__SHOPWARE_ASSOCIATION_REQUIRED_MISSING'; } } diff --git a/src/Migration/Logging/Log/BaseRunLogEntry.php b/src/Migration/Logging/Log/BaseRunLogEntry.php deleted file mode 100644 index 0d22aa7c5..000000000 --- a/src/Migration/Logging/Log/BaseRunLogEntry.php +++ /dev/null @@ -1,51 +0,0 @@ - - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace SwagMigrationAssistant\Migration\Logging\Log; - -use Shopware\Core\Framework\Log\Package; - -#[Package('fundamentals@after-sales')] -abstract class BaseRunLogEntry implements LogEntryInterface -{ - public function __construct( - protected string $runId, - protected ?string $entity = null, - protected ?string $sourceId = null, - ) { - } - - public function getRunId(): ?string - { - return $this->runId; - } - - public function getEntity(): ?string - { - return $this->entity; - } - - public function getSourceId(): ?string - { - return $this->sourceId; - } - - public function getSnippetRoot(): string - { - return 'swag-migration.index.error'; - } - - public function getTitleSnippet(): string - { - return \sprintf('%s.%s.title', $this->getSnippetRoot(), $this->getCode()); - } - - public function getDescriptionSnippet(): string - { - return \sprintf('%s.%s.description', $this->getSnippetRoot(), $this->getCode()); - } -} diff --git a/src/Migration/Logging/Log/Builder/AbstractMigrationLogEntry.php b/src/Migration/Logging/Log/Builder/AbstractMigrationLogEntry.php new file mode 100644 index 000000000..c013a93bf --- /dev/null +++ b/src/Migration/Logging/Log/Builder/AbstractMigrationLogEntry.php @@ -0,0 +1,103 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Migration\Logging\Log\Builder; + +use Shopware\Core\Framework\Log\Package; + +#[Package('fundamentals@after-sales')] +abstract readonly class AbstractMigrationLogEntry implements MigrationLogEntry +{ + final public const LOG_LEVEL_INFO = 'info'; + final public const LOG_LEVEL_WARNING = 'warning'; + final public const LOG_LEVEL_ERROR = 'error'; + final public const LOG_LEVEL_DEBUG = 'debug'; + + /** + * @param array|null $sourceData + * @param array|null $convertedData + * @param array|null $exceptionTrace + */ + public function __construct( + protected string $runId, + protected string $profileName, + protected string $gatewayName, + protected ?string $entityId = null, + protected ?string $entityName = null, + protected ?string $fieldName = null, + protected ?string $fieldSourcePath = null, + protected ?array $sourceData = null, + protected ?array $convertedData = null, + protected ?string $exceptionMessage = null, + protected ?array $exceptionTrace = null, + ) { + } + + public function getRunId(): string + { + return $this->runId; + } + + public function getProfileName(): string + { + return $this->profileName; + } + + public function getGatewayName(): string + { + return $this->gatewayName; + } + + public function getEntityName(): ?string + { + return $this->entityName; + } + + public function getFieldName(): ?string + { + return $this->fieldName; + } + + public function getFieldSourcePath(): ?string + { + return $this->fieldSourcePath; + } + + /** + * @return array|null + */ + public function getSourceData(): ?array + { + return $this->sourceData; + } + + /** + * @return array|null + */ + public function getConvertedData(): ?array + { + return $this->convertedData; + } + + public function getExceptionMessage(): ?string + { + return $this->exceptionMessage; + } + + /** + * @return array|null + */ + public function getExceptionTrace(): ?array + { + return $this->exceptionTrace; + } + + public function getEntityId(): ?string + { + return $this->entityId; + } +} diff --git a/src/Migration/Logging/Log/Builder/MigrationLogBuilder.php b/src/Migration/Logging/Log/Builder/MigrationLogBuilder.php new file mode 100644 index 000000000..1f59f2260 --- /dev/null +++ b/src/Migration/Logging/Log/Builder/MigrationLogBuilder.php @@ -0,0 +1,159 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Migration\Logging\Log\Builder; + +use Shopware\Core\Framework\Log\Package; +use Shopware\Core\Framework\Uuid\Uuid; +use SwagMigrationAssistant\Exception\MigrationException; +use SwagMigrationAssistant\Migration\MigrationContextInterface; + +/** + * @example + * $log = (new MigrationLogBuilder('runId', 'profileName', 'gatewayName')) + * ->withField('fieldName') + * ->withFieldSourcePath('sourcePath') + * ->build(MigrationLogEntry::class); + */ +#[Package('fundamentals@after-sales')] +class MigrationLogBuilder +{ + /** + * @param array|null $sourceData + * @param array|null $convertedData + * @param array|null $exceptionTrace + */ + public function __construct( + protected string $runId, + protected string $profileName, + protected string $gatewayName, + protected ?string $entityId = null, + protected ?string $entityName = null, + protected ?string $fieldName = null, + protected ?string $fieldSourcePath = null, + protected ?array $sourceData = null, + protected ?array $convertedData = null, + protected ?string $exceptionMessage = null, + protected ?array $exceptionTrace = null, + ) { + } + + public static function fromMigrationContext(MigrationContextInterface $migrationContext): self + { + return new self( + $migrationContext->getRunUuid(), + $migrationContext->getConnection()->getProfileName(), + $migrationContext->getConnection()->getGatewayName(), + ); + } + + public function withEntityName(string $entityName): self + { + $this->entityName = $entityName; + + return $this; + } + + public function withFieldName(string $field): self + { + $this->fieldName = $field; + + return $this; + } + + public function withFieldSourcePath(string $fieldSourcePath): self + { + $this->fieldSourcePath = $fieldSourcePath; + + return $this; + } + + public function withEntityId(?string $entityId): self + { + $this->entityId = $this->getRevisedId($entityId); + + return $this; + } + + /** + * @param array $sourceData + */ + public function withSourceData(array $sourceData): self + { + $this->sourceData = $sourceData; + + return $this; + } + + /** + * @param array $convertedData + */ + public function withConvertedData(array $convertedData): self + { + $this->convertedData = $convertedData; + + return $this; + } + + public function withExceptionMessage(string $exceptionMessage): self + { + $this->exceptionMessage = $exceptionMessage; + + return $this; + } + + /** + * @param array $exceptionTrace + */ + public function withExceptionTrace(array $exceptionTrace): self + { + $this->exceptionTrace = $exceptionTrace; + + return $this; + } + + /** + * @template T of AbstractMigrationLogEntry + * + * @param class-string $logClass + * + * @return T + */ + public function build(string $logClass): AbstractMigrationLogEntry + { + if (!class_exists($logClass) || !is_subclass_of($logClass, AbstractMigrationLogEntry::class)) { + throw MigrationException::failedToCreateMigrationLog($logClass); + } + + return new $logClass( + $this->runId, + $this->profileName, + $this->gatewayName, + $this->entityId, + $this->entityName, + $this->fieldName, + $this->fieldSourcePath, + $this->sourceData, + $this->convertedData, + $this->exceptionMessage, + $this->exceptionTrace, + ); + } + + private function getRevisedId(?string $id): ?string + { + if ($id === null) { + return null; + } + + if (Uuid::isValid($id)) { + return $id; + } + + return null; + } +} diff --git a/src/Migration/Logging/Log/Builder/MigrationLogEntry.php b/src/Migration/Logging/Log/Builder/MigrationLogEntry.php new file mode 100644 index 000000000..38794af7e --- /dev/null +++ b/src/Migration/Logging/Log/Builder/MigrationLogEntry.php @@ -0,0 +1,51 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Migration\Logging\Log\Builder; + +use Shopware\Core\Framework\Log\Package; + +#[Package('fundamentals@after-sales')] +interface MigrationLogEntry +{ + public function getRunId(): string; + + public function getProfileName(): string; + + public function getGatewayName(): string; + + public function getLevel(): string; + + public function getCode(): string; + + public function isUserFixable(): bool; + + public function getEntityId(): ?string; + + public function getEntityName(): ?string; + + public function getFieldName(): ?string; + + public function getFieldSourcePath(): ?string; + + /** + * @return array|null + */ + public function getSourceData(): ?array; + + /** + * @return array|null + */ + public function getConvertedData(): ?array; + + public function getExceptionMessage(): ?string; + + /** + * @return array|null + */ + public function getExceptionTrace(): ?array; +} diff --git a/src/Migration/Logging/Log/CannotConvertChildEntity.php b/src/Migration/Logging/Log/CannotConvertChildEntity.php deleted file mode 100644 index f97224fb3..000000000 --- a/src/Migration/Logging/Log/CannotConvertChildEntity.php +++ /dev/null @@ -1,82 +0,0 @@ - - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace SwagMigrationAssistant\Migration\Logging\Log; - -use Shopware\Core\Framework\Log\Package; - -#[Package('fundamentals@after-sales')] -class CannotConvertChildEntity extends BaseRunLogEntry -{ - public function __construct( - string $runId, - string $entity, - private readonly string $parentEntity, - private readonly string $parentSourceId, - ) { - parent::__construct($runId, $entity, null); - } - - public function getLevel(): string - { - return self::LOG_LEVEL_WARNING; - } - - public function getCode(): string - { - $entity = $this->getEntity(); - if ($entity === null) { - return 'SWAG_MIGRATION_CANNOT_CONVERT_CHILD_ENTITY'; - } - - return \sprintf('SWAG_MIGRATION_CANNOT_CONVERT_CHILD_%s_ENTITY', \mb_strtoupper($entity)); - } - - public function getTitle(): string - { - $entity = $this->getEntity(); - if ($entity === null) { - return 'The child entity could not be converted'; - } - - return \sprintf('The %s child entity could not be converted', $entity); - } - - /** - * @return array{entity: ?string, parentEntity: string, parentSourceId: string} - */ - public function getParameters(): array - { - return [ - 'entity' => $this->getEntity(), - 'parentEntity' => $this->parentEntity, - 'parentSourceId' => $this->parentSourceId, - ]; - } - - public function getDescription(): string - { - $args = $this->getParameters(); - - return \sprintf( - 'The %s child entity from the %s parent entity with the id "%s" could not be converted.', - $args['entity'], - $args['parentEntity'], - $args['parentSourceId'] - ); - } - - public function getTitleSnippet(): string - { - return \sprintf('%s.%s.title', $this->getSnippetRoot(), 'SWAG_MIGRATION_CANNOT_CONVERT_CHILD_ENTITY'); - } - - public function getDescriptionSnippet(): string - { - return \sprintf('%s.%s.description', $this->getSnippetRoot(), 'SWAG_MIGRATION_CANNOT_CONVERT_CHILD_ENTITY'); - } -} diff --git a/src/Migration/Logging/Log/CannotConvertChildEntityLog.php b/src/Migration/Logging/Log/CannotConvertChildEntityLog.php new file mode 100644 index 000000000..c97f8a621 --- /dev/null +++ b/src/Migration/Logging/Log/CannotConvertChildEntityLog.php @@ -0,0 +1,30 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Migration\Logging\Log; + +use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; + +#[Package('fundamentals@after-sales')] +readonly class CannotConvertChildEntityLog extends AbstractMigrationLogEntry +{ + public function isUserFixable(): bool + { + return false; + } + + public function getLevel(): string + { + return self::LOG_LEVEL_WARNING; + } + + public function getCode(): string + { + return 'SWAG_MIGRATION_CANNOT_CONVERT_CHILD_ENTITY'; + } +} diff --git a/src/Migration/Logging/Log/CannotConvertEntity.php b/src/Migration/Logging/Log/CannotConvertEntity.php deleted file mode 100644 index 12588ae3d..000000000 --- a/src/Migration/Logging/Log/CannotConvertEntity.php +++ /dev/null @@ -1,79 +0,0 @@ - - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace SwagMigrationAssistant\Migration\Logging\Log; - -use Shopware\Core\Framework\Log\Package; - -#[Package('fundamentals@after-sales')] -class CannotConvertEntity extends BaseRunLogEntry -{ - public function __construct( - string $runId, - string $entity, - string $sourceId, - ) { - parent::__construct($runId, $entity, $sourceId); - } - - public function getLevel(): string - { - return self::LOG_LEVEL_WARNING; - } - - public function getCode(): string - { - $entity = $this->getEntity(); - if ($entity === null) { - return 'SWAG_MIGRATION_CANNOT_CONVERT'; - } - - return \sprintf('SWAG_MIGRATION_CANNOT_CONVERT_%s', \mb_strtoupper($entity)); - } - - public function getTitle(): string - { - $entity = $this->getEntity(); - if ($entity === null) { - return 'The entity could not be converted'; - } - - return \sprintf('The %s entity could not be converted', $entity); - } - - /** - * @return array{entity: ?string, sourceId: ?string} - */ - public function getParameters(): array - { - return [ - 'entity' => $this->getEntity(), - 'sourceId' => $this->getSourceId(), - ]; - } - - public function getDescription(): string - { - $args = $this->getParameters(); - - return \sprintf( - 'The %s entity with the source id "%s" could not be converted.', - $args['entity'], - $args['sourceId'] ?? 'null' - ); - } - - public function getTitleSnippet(): string - { - return \sprintf('%s.%s.title', $this->getSnippetRoot(), 'SWAG_MIGRATION_CANNOT_CONVERT_ENTITY'); - } - - public function getDescriptionSnippet(): string - { - return \sprintf('%s.%s.description', $this->getSnippetRoot(), 'SWAG_MIGRATION_CANNOT_CONVERT_ENTITY'); - } -} diff --git a/src/Migration/Logging/Log/CannotConvertEntityLog.php b/src/Migration/Logging/Log/CannotConvertEntityLog.php new file mode 100644 index 000000000..59b335aad --- /dev/null +++ b/src/Migration/Logging/Log/CannotConvertEntityLog.php @@ -0,0 +1,30 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Migration\Logging\Log; + +use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; + +#[Package('fundamentals@after-sales')] +readonly class CannotConvertEntityLog extends AbstractMigrationLogEntry +{ + public function isUserFixable(): bool + { + return false; + } + + public function getLevel(): string + { + return self::LOG_LEVEL_WARNING; + } + + public function getCode(): string + { + return 'SWAG_MIGRATION_CANNOT_CONVERT'; + } +} diff --git a/src/Migration/Logging/Log/CannotGetFileRunLog.php b/src/Migration/Logging/Log/CannotGetFileRunLog.php index 56397ae6e..06fc4a512 100644 --- a/src/Migration/Logging/Log/CannotGetFileRunLog.php +++ b/src/Migration/Logging/Log/CannotGetFileRunLog.php @@ -7,20 +7,15 @@ namespace SwagMigrationAssistant\Migration\Logging\Log; -use GuzzleHttp\Exception\RequestException; use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; #[Package('fundamentals@after-sales')] -class CannotGetFileRunLog extends BaseRunLogEntry +readonly class CannotGetFileRunLog extends AbstractMigrationLogEntry { - public function __construct( - string $runId, - string $entity, - string $sourceId, - private readonly string $uri, - private readonly ?RequestException $requestException = null, - ) { - parent::__construct($runId, $entity, $sourceId); + public function isUserFixable(): bool + { + return false; } public function getLevel(): string @@ -30,64 +25,6 @@ public function getLevel(): string public function getCode(): string { - $entity = $this->getEntity(); - if ($entity === null) { - return 'SWAG_MIGRATION_CANNOT_GET_FILE'; - } - - return \sprintf('SWAG_MIGRATION_CANNOT_GET_%s_FILE', \mb_strtoupper($entity)); - } - - public function getTitle(): string - { - $entity = $this->getEntity(); - if ($entity === null) { - return 'The file cannot be downloaded / copied'; - } - - return \sprintf('The %s file cannot be downloaded / copied', $entity); - } - - /** - * @return array{entity: ?string, sourceId: ?string, uri: string} - */ - public function getParameters(): array - { - return [ - 'entity' => $this->getEntity(), - 'sourceId' => $this->getSourceId(), - 'uri' => $this->uri, - ]; - } - - public function getDescription(): string - { - $args = $this->getParameters(); - - $description = \sprintf( - 'The %s file with the uri "%s" and media id "%s" cannot be downloaded / copied.', - $args['entity'], - $args['uri'], - $args['sourceId'] - ); - - if ($this->requestException !== null) { - $description .= \sprintf( - ' The following request error occurred: %s', - $this->requestException->getMessage() - ); - } - - return $description; - } - - public function getTitleSnippet(): string - { - return \sprintf('%s.%s.title', $this->getSnippetRoot(), 'SWAG_MIGRATION_CANNOT_GET_FILE'); - } - - public function getDescriptionSnippet(): string - { - return \sprintf('%s.%s.description', $this->getSnippetRoot(), 'SWAG_MIGRATION_CANNOT_GET_FILE'); + return 'SWAG_MIGRATION_CANNOT_GET_FILE'; } } diff --git a/src/Migration/Logging/Log/CannotReadEntityCountLog.php b/src/Migration/Logging/Log/CannotReadEntityCountLog.php index e3e55641b..70cd3af77 100644 --- a/src/Migration/Logging/Log/CannotReadEntityCountLog.php +++ b/src/Migration/Logging/Log/CannotReadEntityCountLog.php @@ -8,19 +8,14 @@ namespace SwagMigrationAssistant\Migration\Logging\Log; use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; #[Package('fundamentals@after-sales')] -class CannotReadEntityCountLog extends BaseRunLogEntry +readonly class CannotReadEntityCountLog extends AbstractMigrationLogEntry { - public function __construct( - string $runUuid, - string $entity, - private readonly string $table, - private readonly ?string $condition, - private readonly string $exceptionCode, - private readonly string $exceptionMessage, - ) { - parent::__construct($runUuid, $entity); + public function isUserFixable(): bool + { + return false; } public function getLevel(): string @@ -32,36 +27,4 @@ public function getCode(): string { return 'SWAG_MIGRATION__COULD_NOT_READ_ENTITY_COUNT'; } - - public function getTitle(): string - { - return 'Could not read entity count'; - } - - /** - * @return array{entity: ?string, table: string, condition: ?string, exceptionCode: string, exceptionMessage: string} - */ - public function getParameters(): array - { - return [ - 'entity' => $this->getEntity(), - 'table' => $this->table, - 'condition' => $this->condition, - 'exceptionCode' => $this->exceptionCode, - 'exceptionMessage' => $this->exceptionMessage, - ]; - } - - public function getDescription(): string - { - $args = $this->getParameters(); - - return \sprintf( - 'Total count for entity %s could not be read. Make sure the table %s exists in your source system and the optional condition "%s" is valid. Exception message: %s', - $args['entity'], - $args['table'], - $args['condition'], - $args['exceptionMessage'] - ); - } } diff --git a/src/Migration/Logging/Log/DataSetNotFoundLog.php b/src/Migration/Logging/Log/DataSetNotFoundLog.php index 1119a2bbd..72b4bc6f1 100644 --- a/src/Migration/Logging/Log/DataSetNotFoundLog.php +++ b/src/Migration/Logging/Log/DataSetNotFoundLog.php @@ -8,17 +8,14 @@ namespace SwagMigrationAssistant\Migration\Logging\Log; use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; #[Package('fundamentals@after-sales')] -class DataSetNotFoundLog extends BaseRunLogEntry +readonly class DataSetNotFoundLog extends AbstractMigrationLogEntry { - public function __construct( - string $runUuid, - string $entity, - string $sourceId, - private readonly string $profileName, - ) { - parent::__construct($runUuid, $entity, $sourceId); + public function isUserFixable(): bool + { + return false; } public function getLevel(): string @@ -30,33 +27,4 @@ public function getCode(): string { return 'SWAG_MIGRATION__DATASET_NOT_FOUND'; } - - public function getTitle(): string - { - return 'DataSet not found'; - } - - /** - * @return array{profileName: string, entity: ?string, sourceId: ?string} - */ - public function getParameters(): array - { - return [ - 'profileName' => $this->profileName, - 'entity' => $this->getEntity(), - 'sourceId' => $this->getSourceId(), - ]; - } - - public function getDescription(): string - { - $args = $this->getParameters(); - - return \sprintf( - 'DataSet for profile "%s" and entity "%s" not found. Entity with id "%s" could not be processed.', - $args['profileName'], - $args['entity'], - $args['sourceId'] - ); - } } diff --git a/src/Migration/Logging/Log/DebugLog.php b/src/Migration/Logging/Log/DebugLog.php index e916e2295..758c090c3 100644 --- a/src/Migration/Logging/Log/DebugLog.php +++ b/src/Migration/Logging/Log/DebugLog.php @@ -8,76 +8,96 @@ namespace SwagMigrationAssistant\Migration\Logging\Log; use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogEntry; #[Package('fundamentals@after-sales')] -class DebugLog implements LogEntryInterface +readonly class DebugLog implements MigrationLogEntry { /** - * @param array $logData + * @param array $logData */ public function __construct( - private readonly array $logData, - private readonly ?string $runId, + private string $runId, + private array $logData, ) { } - public function getLevel(): string + /** + * @return array + */ + public function getLogData(): array { - return self::LOG_LEVEL_DEBUG; + return $this->logData; } - public function getCode(): string + public function getRunId(): string { - return 'SWAG_MIGRATION__DEBUG'; + return $this->runId; } - public function getTitle(): string + public function isUserFixable(): bool { - return 'Debug'; + return false; } - /** - * @return array{logData: array} - */ - public function getParameters(): array + public function getProfileName(): string { - return [ - 'logData' => $this->logData, - ]; + return 'Debug Profile'; } - public function getDescription(): string + public function getGatewayName(): string { - return (string) \json_encode($this->logData); + return 'Debug Gateway'; } - public function getSnippetRoot(): string + public function getLevel(): string { - return 'swag-migration.index.error'; + return AbstractMigrationLogEntry::LOG_LEVEL_DEBUG; } - public function getTitleSnippet(): string + public function getCode(): string { - return \sprintf('%s.%s.title', $this->getSnippetRoot(), $this->getCode()); + return 'SWAG_MIGRATION__DEBUG'; } - public function getDescriptionSnippet(): string + public function getEntityName(): ?string { - return \sprintf('%s.%s.description', $this->getSnippetRoot(), $this->getCode()); + return null; } - public function getEntity(): ?string + public function getFieldName(): ?string { return null; } - public function getSourceId(): ?string + public function getFieldSourcePath(): ?string { return null; } - public function getRunId(): ?string + public function getSourceData(): ?array { - return $this->runId; + return null; + } + + public function getConvertedData(): ?array + { + return null; + } + + public function getExceptionMessage(): ?string + { + return null; + } + + public function getExceptionTrace(): ?array + { + return null; + } + + public function getEntityId(): ?string + { + return null; } } diff --git a/src/Migration/Logging/Log/DocumentTypeNotSupported.php b/src/Migration/Logging/Log/DocumentTypeNotSupported.php deleted file mode 100644 index 09338f098..000000000 --- a/src/Migration/Logging/Log/DocumentTypeNotSupported.php +++ /dev/null @@ -1,60 +0,0 @@ - - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace SwagMigrationAssistant\Migration\Logging\Log; - -use Shopware\Core\Framework\Log\Package; -use SwagMigrationAssistant\Migration\DataSelection\DefaultEntities; - -#[Package('fundamentals@after-sales')] -class DocumentTypeNotSupported extends BaseRunLogEntry -{ - public function __construct( - string $runId, - string $sourceId, - private readonly string $type, - ) { - parent::__construct($runId, DefaultEntities::ORDER_DOCUMENT, $sourceId); - } - - public function getLevel(): string - { - return self::LOG_LEVEL_WARNING; - } - - public function getCode(): string - { - return 'SWAG_MIGRATION__DOCUMENT_TYPE_NOT_SUPPORTED'; - } - - public function getTitle(): string - { - return 'Document type is not supported'; - } - - /** - * @return array{sourceId: ?string, type: string} - */ - public function getParameters(): array - { - return [ - 'sourceId' => $this->getSourceId(), - 'type' => $this->type, - ]; - } - - public function getDescription(): string - { - $args = $this->getParameters(); - - return \sprintf( - 'The document with the source id "%s" has the document type "%s", which just got migrated but is still missing a document renderer. If you want to generate documents of this type, please follow this documentation: https://developer.shopware.com/docs/guides/plugins/plugins/checkout/document/add-custom-document-type.html', - $args['sourceId'], - $args['type'] - ); - } -} diff --git a/src/Migration/Logging/Log/DocumentTypeNotSupportedLog.php b/src/Migration/Logging/Log/DocumentTypeNotSupportedLog.php new file mode 100644 index 000000000..6eed88c34 --- /dev/null +++ b/src/Migration/Logging/Log/DocumentTypeNotSupportedLog.php @@ -0,0 +1,30 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Migration\Logging\Log; + +use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; + +#[Package('fundamentals@after-sales')] +readonly class DocumentTypeNotSupportedLog extends AbstractMigrationLogEntry +{ + public function isUserFixable(): bool + { + return false; + } + + public function getLevel(): string + { + return self::LOG_LEVEL_WARNING; + } + + public function getCode(): string + { + return 'SWAG_MIGRATION__DOCUMENT_TYPE_NOT_SUPPORTED'; + } +} diff --git a/src/Migration/Logging/Log/EmptyNecessaryFieldRunLog.php b/src/Migration/Logging/Log/EmptyNecessaryFieldRunLog.php index ccfce6da1..0115a2383 100644 --- a/src/Migration/Logging/Log/EmptyNecessaryFieldRunLog.php +++ b/src/Migration/Logging/Log/EmptyNecessaryFieldRunLog.php @@ -8,75 +8,23 @@ namespace SwagMigrationAssistant\Migration\Logging\Log; use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; #[Package('fundamentals@after-sales')] -class EmptyNecessaryFieldRunLog extends BaseRunLogEntry +readonly class EmptyNecessaryFieldRunLog extends AbstractMigrationLogEntry { - public function __construct( - string $runId, - string $entity, - string $sourceId, - private readonly string $emptyField, - ) { - parent::__construct($runId, $entity, $sourceId); + public function isUserFixable(): bool + { + return false; } public function getCode(): string { - $entity = $this->getEntity(); - if ($entity === null) { - return 'SWAG_MIGRATION_EMPTY_NECESSARY_FIELD'; - } - - return \sprintf('SWAG_MIGRATION_EMPTY_NECESSARY_FIELD_%s', \mb_strtoupper($entity)); + return 'SWAG_MIGRATION_EMPTY_NECESSARY_FIELD'; } public function getLevel(): string { return self::LOG_LEVEL_WARNING; } - - public function getTitle(): string - { - $entity = $this->getEntity(); - if ($entity === null) { - return 'The entity has one or more empty necessary fields'; - } - - return \sprintf('The %s entity has one or more empty necessary fields', $entity); - } - - /** - * @return array{entity: ?string, sourceId: ?string, emptyField: string} - */ - public function getParameters(): array - { - return [ - 'entity' => $this->getEntity(), - 'sourceId' => $this->getSourceId(), - 'emptyField' => $this->emptyField, - ]; - } - - public function getDescription(): string - { - $args = $this->getParameters(); - - return \sprintf( - 'The %s entity with the source id %s does not have the necessary data for the field(s): %s', - $args['entity'], - $args['sourceId'], - $args['emptyField'] - ); - } - - public function getTitleSnippet(): string - { - return \sprintf('%s.%s.title', $this->getSnippetRoot(), 'SWAG_MIGRATION__SHOPWARE_EMPTY_NECESSARY_DATA_FIELDS'); - } - - public function getDescriptionSnippet(): string - { - return \sprintf('%s.%s.description', $this->getSnippetRoot(), 'SWAG_MIGRATION__SHOPWARE_EMPTY_NECESSARY_DATA_FIELDS'); - } } diff --git a/src/Migration/Logging/Log/EntityAlreadyExistsRunLog.php b/src/Migration/Logging/Log/EntityAlreadyExistsRunLog.php index f176f71fc..b83b49153 100644 --- a/src/Migration/Logging/Log/EntityAlreadyExistsRunLog.php +++ b/src/Migration/Logging/Log/EntityAlreadyExistsRunLog.php @@ -8,16 +8,14 @@ namespace SwagMigrationAssistant\Migration\Logging\Log; use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; #[Package('fundamentals@after-sales')] -class EntityAlreadyExistsRunLog extends BaseRunLogEntry +readonly class EntityAlreadyExistsRunLog extends AbstractMigrationLogEntry { - public function __construct( - string $runId, - string $entity, - string $sourceId, - ) { - parent::__construct($runId, $entity, $sourceId); + public function isUserFixable(): bool + { + return false; } public function getLevel(): string @@ -27,53 +25,6 @@ public function getLevel(): string public function getCode(): string { - $entity = $this->getEntity(); - if ($entity === null) { - return 'SWAG_MIGRATION_ENTITY_ALREADY_EXISTS'; - } - - return \sprintf('SWAG_MIGRATION_%s_ENTITY_ALREADY_EXISTS', \mb_strtoupper($entity)); - } - - public function getTitle(): string - { - $entity = $this->getEntity(); - if ($entity === null) { - return 'The entity already exists'; - } - - return \sprintf('The %s entity already exists', $entity); - } - - /** - * @return array{entity: ?string, sourceId: ?string} - */ - public function getParameters(): array - { - return [ - 'entity' => $this->getEntity(), - 'sourceId' => $this->getSourceId(), - ]; - } - - public function getDescription(): string - { - $args = $this->getParameters(); - - return \sprintf( - 'The %s entity with source id "%s" already exists and cannot be written.', - $args['entity'], - $args['sourceId'] - ); - } - - public function getTitleSnippet(): string - { - return \sprintf('%s.%s.title', $this->getSnippetRoot(), 'SWAG_MIGRATION_ENTITY_ALREADY_EXISTS'); - } - - public function getDescriptionSnippet(): string - { - return \sprintf('%s.%s.description', $this->getSnippetRoot(), 'SWAG_MIGRATION_ENTITY_ALREADY_EXISTS'); + return 'SWAG_MIGRATION_ENTITY_ALREADY_EXISTS'; } } diff --git a/src/Migration/Logging/Log/ExceptionRunLog.php b/src/Migration/Logging/Log/ExceptionRunLog.php index 5e558213a..1576d4464 100644 --- a/src/Migration/Logging/Log/ExceptionRunLog.php +++ b/src/Migration/Logging/Log/ExceptionRunLog.php @@ -8,18 +8,14 @@ namespace SwagMigrationAssistant\Migration\Logging\Log; use Shopware\Core\Framework\Log\Package; -use Shopware\Core\Framework\ShopwareHttpException; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; #[Package('fundamentals@after-sales')] -class ExceptionRunLog extends BaseRunLogEntry +readonly class ExceptionRunLog extends AbstractMigrationLogEntry { - public function __construct( - string $runId, - string $entity, - private readonly \Throwable $exception, - ?string $sourceId = null, - ) { - parent::__construct($runId, $entity, $sourceId); + public function isUserFixable(): bool + { + return false; } public function getLevel(): string @@ -31,42 +27,4 @@ public function getCode(): string { return 'SWAG_MIGRATION_RUN_EXCEPTION'; } - - public function getTitle(): string - { - return 'An exception occurred'; - } - - /** - * @return array{entity: ?string, sourceId: ?string, exceptionCode: int|string, exceptionMessage: ?string, exceptionFile: string, exceptionLine: int, exceptionTrace: ?string, description: string} - */ - public function getParameters(): array - { - $entity = $this->getEntity() ?? '-'; - $errorCode = $this->exception->getCode(); - if (\is_subclass_of($this->exception, ShopwareHttpException::class)) { - $errorCode = $this->exception->getErrorCode(); - } - - return [ - 'entity' => $this->getEntity(), - 'sourceId' => $this->getSourceId(), - 'exceptionCode' => $errorCode, - 'exceptionMessage' => \preg_replace('/[[:^print:]]/', '', $this->exception->getMessage()), - 'exceptionFile' => $this->exception->getFile(), - 'exceptionLine' => $this->exception->getLine(), - 'exceptionTrace' => \preg_replace('/[[:^print:]]/', '', $this->exception->getTraceAsString()), - 'description' => \sprintf( - 'Entity: %s, sourceId: %s' . \PHP_EOL . '%s', - $entity, - $this->getSourceId() ?? '-', - \preg_replace('/[[:^print:]]/', '', $this->exception->getMessage()) - ), - ]; - } - - public function getDescription(): string - { - return $this->getParameters()['description']; - } } diff --git a/src/Migration/Logging/Log/FieldReassignedRunLog.php b/src/Migration/Logging/Log/FieldReassignedRunLog.php index e47519f69..2e0b91d87 100644 --- a/src/Migration/Logging/Log/FieldReassignedRunLog.php +++ b/src/Migration/Logging/Log/FieldReassignedRunLog.php @@ -8,18 +8,14 @@ namespace SwagMigrationAssistant\Migration\Logging\Log; use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; #[Package('fundamentals@after-sales')] -class FieldReassignedRunLog extends BaseRunLogEntry +readonly class FieldReassignedRunLog extends AbstractMigrationLogEntry { - public function __construct( - string $runId, - string $entity, - string $sourceId, - private readonly string $emptyField, - private readonly string $replacementField, - ) { - parent::__construct($runId, $entity, $sourceId); + public function isUserFixable(): bool + { + return false; } public function getLevel(): string @@ -29,57 +25,6 @@ public function getLevel(): string public function getCode(): string { - $entity = $this->getEntity(); - if ($entity === null) { - return 'SWAG_MIGRATION_ENTITY_FIELD_REASSIGNED'; - } - - return \sprintf('SWAG_MIGRATION_%s_ENTITY_FIELD_REASSIGNED', \mb_strtoupper($entity)); - } - - public function getTitle(): string - { - $entity = $this->getEntity(); - if ($entity === null) { - return 'The entity has a field that was reassigned'; - } - - return \sprintf('The %s entity has a field that was reassigned', $entity); - } - - /** - * @return array{entity: ?string, sourceId: ?string, emptyField: string, replacementField: string} - */ - public function getParameters(): array - { - return [ - 'entity' => $this->getEntity(), - 'sourceId' => $this->getSourceId(), - 'emptyField' => $this->emptyField, - 'replacementField' => $this->replacementField, - ]; - } - - public function getDescription(): string - { - $args = $this->getParameters(); - - return \sprintf( - 'The %s entity with the source id "%s" got the field %s replaced with %s.', - $args['entity'], - $args['sourceId'], - $args['emptyField'], - $args['replacementField'] - ); - } - - public function getTitleSnippet(): string - { - return \sprintf('%s.%s.title', $this->getSnippetRoot(), 'SWAG_MIGRATION_ENTITY_FIELD_REASSIGNED'); - } - - public function getDescriptionSnippet(): string - { - return \sprintf('%s.%s.description', $this->getSnippetRoot(), 'SWAG_MIGRATION_ENTITY_FIELD_REASSIGNED'); + return 'SWAG_MIGRATION_ENTITY_FIELD_REASSIGNED'; } } diff --git a/src/Migration/Logging/Log/InvalidUnserializedData.php b/src/Migration/Logging/Log/InvalidUnserializedData.php deleted file mode 100644 index dabdad73b..000000000 --- a/src/Migration/Logging/Log/InvalidUnserializedData.php +++ /dev/null @@ -1,65 +0,0 @@ - - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace SwagMigrationAssistant\Migration\Logging\Log; - -use Shopware\Core\Framework\Log\Package; - -#[Package('fundamentals@after-sales')] -class InvalidUnserializedData extends BaseRunLogEntry -{ - public function __construct( - string $runId, - string $entity, - string $sourceId, - private readonly string $unserializedEntity, - private readonly string $serializedData, - ) { - parent::__construct($runId, $entity, $sourceId); - } - - public function getLevel(): string - { - return self::LOG_LEVEL_WARNING; - } - - public function getCode(): string - { - return 'SWAG_MIGRATION__SHOPWARE_INVALID_UNSERIALIZED_DATA'; - } - - public function getTitle(): string - { - return 'Invalid unserialized data'; - } - - /** - * @return array{entity: ?string, sourceId: ?string, unserializedEntity: string, serializedData: string} - */ - public function getParameters(): array - { - return [ - 'entity' => $this->getEntity(), - 'sourceId' => $this->getSourceId(), - 'unserializedEntity' => $this->unserializedEntity, - 'serializedData' => $this->serializedData, - ]; - } - - public function getDescription(): string - { - $args = $this->getParameters(); - - return \sprintf( - 'The %s entity with source id "%s" could not be converted because of invalid unserialized object data for the "%s" entity and the raw data is: %s', - $args['entity'], - $args['sourceId'], - $args['unserializedEntity'], - $args['serializedData'] - ); - } -} diff --git a/src/Migration/Logging/Log/InvalidUnserializedDataLog.php b/src/Migration/Logging/Log/InvalidUnserializedDataLog.php new file mode 100644 index 000000000..ac366a2b8 --- /dev/null +++ b/src/Migration/Logging/Log/InvalidUnserializedDataLog.php @@ -0,0 +1,30 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Migration\Logging\Log; + +use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; + +#[Package('fundamentals@after-sales')] +readonly class InvalidUnserializedDataLog extends AbstractMigrationLogEntry +{ + public function isUserFixable(): bool + { + return false; + } + + public function getLevel(): string + { + return self::LOG_LEVEL_WARNING; + } + + public function getCode(): string + { + return 'SWAG_MIGRATION__SHOPWARE_INVALID_UNSERIALIZED_DATA'; + } +} diff --git a/src/Migration/Logging/Log/LogEntryInterface.php b/src/Migration/Logging/Log/LogEntryInterface.php deleted file mode 100644 index 68d964b15..000000000 --- a/src/Migration/Logging/Log/LogEntryInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace SwagMigrationAssistant\Migration\Logging\Log; - -use Shopware\Core\Framework\Log\Package; - -#[Package('fundamentals@after-sales')] -interface LogEntryInterface -{ - final public const LOG_LEVEL_INFO = 'info'; - final public const LOG_LEVEL_WARNING = 'warning'; - final public const LOG_LEVEL_ERROR = 'error'; - final public const LOG_LEVEL_DEBUG = 'debug'; - - public function getLevel(): string; - - public function getCode(): string; - - public function getTitle(): string; - - /** - * @return array - */ - public function getParameters(): array; - - public function getDescription(): string; - - public function getTitleSnippet(): string; - - public function getDescriptionSnippet(): string; - - public function getEntity(): ?string; - - public function getSourceId(): ?string; - - public function getRunId(): ?string; -} diff --git a/src/Migration/Logging/Log/MainVariantRelationNotConverted.php b/src/Migration/Logging/Log/MainVariantRelationNotConverted.php new file mode 100644 index 000000000..f1c391502 --- /dev/null +++ b/src/Migration/Logging/Log/MainVariantRelationNotConverted.php @@ -0,0 +1,30 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Migration\Logging\Log; + +use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; + +#[Package('after-sales')] +readonly class MainVariantRelationNotConverted extends AbstractMigrationLogEntry +{ + public function getLevel(): string + { + return self::LOG_LEVEL_ERROR; + } + + public function getCode(): string + { + return 'SWAG_MIGRATION__MAIN_VARIANT_RELATION_NOT_CONVERTED'; + } + + public function isUserFixable(): bool + { + return false; + } +} diff --git a/src/Migration/Logging/Log/MessageQueueExceptionLog.php b/src/Migration/Logging/Log/MessageQueueExceptionLog.php index 36059d14f..bb28b1109 100644 --- a/src/Migration/Logging/Log/MessageQueueExceptionLog.php +++ b/src/Migration/Logging/Log/MessageQueueExceptionLog.php @@ -8,17 +8,14 @@ namespace SwagMigrationAssistant\Migration\Logging\Log; use Shopware\Core\Framework\Log\Package; -use Shopware\Core\Framework\ShopwareHttpException; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; #[Package('fundamentals@after-sales')] -class MessageQueueExceptionLog extends BaseRunLogEntry +readonly class MessageQueueExceptionLog extends AbstractMigrationLogEntry { - public function __construct( - string $runId, - private readonly \Throwable $exception, - private int $exceptionCount, - ) { - parent::__construct($runId); + public function isUserFixable(): bool + { + return false; } public function getLevel(): string @@ -30,40 +27,4 @@ public function getCode(): string { return 'SWAG_MIGRATION_MESSAGE_QUEUE_EXCEPTION'; } - - public function getTitle(): string - { - return 'An exception occurred during the message queue processing'; - } - - /** - * @return array{exceptionCode: int|string, exceptionMessage: ?string, exceptionFile: string, exceptionLine: int, exceptionTrace: ?string, description: string} - */ - public function getParameters(): array - { - $errorCode = $this->exception->getCode(); - if (\is_subclass_of($this->exception, ShopwareHttpException::class)) { - $errorCode = $this->exception->getErrorCode(); - } - - return [ - 'exceptionCount' => $this->exceptionCount, - 'exceptionCode' => $errorCode, - 'exceptionMessage' => \preg_replace('/[[:^print:]]/', '', $this->exception->getMessage()), - 'exceptionFile' => $this->exception->getFile(), - 'exceptionLine' => $this->exception->getLine(), - 'exceptionTrace' => \preg_replace('/[[:^print:]]/', '', $this->exception->getTraceAsString()), - 'description' => \sprintf( - 'RunId: %s, ExceptionCount: %d ' . \PHP_EOL . '%s', - $this->getRunId(), - $this->exceptionCount, - \preg_replace('/[[:^print:]]/', '', $this->exception->getMessage()) - ), - ]; - } - - public function getDescription(): string - { - return $this->getParameters()['description']; - } } diff --git a/src/Migration/Logging/Log/MimeTypeErrorLog.php b/src/Migration/Logging/Log/MimeTypeErrorLog.php index a38790d1d..ba02236ae 100644 --- a/src/Migration/Logging/Log/MimeTypeErrorLog.php +++ b/src/Migration/Logging/Log/MimeTypeErrorLog.php @@ -8,16 +8,14 @@ namespace SwagMigrationAssistant\Migration\Logging\Log; use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; #[Package('fundamentals@after-sales')] -class MimeTypeErrorLog extends BaseRunLogEntry +readonly class MimeTypeErrorLog extends AbstractMigrationLogEntry { - public function __construct( - string $runId, - string $entity, - ?string $sourceId = null, - ) { - parent::__construct($runId, $entity, $sourceId); + public function isUserFixable(): bool + { + return false; } public function getLevel(): string @@ -29,27 +27,4 @@ public function getCode(): string { return 'SWAG_MIGRATION__MIME_TYPE_COULD_NOT_BE_DETERMINED'; } - - public function getTitle(): string - { - return 'An exception occurred'; - } - - /** - * @return array{entity: ?string, sourceId: ?string, exceptionCode: int|string, description: string} - */ - public function getParameters(): array - { - return [ - 'entity' => $this->getEntity(), - 'sourceId' => $this->getSourceId(), - 'exceptionCode' => $this->getCode(), - 'description' => 'Could not determine the mime type', - ]; - } - - public function getDescription(): string - { - return $this->getParameters()['description']; - } } diff --git a/src/Migration/Logging/Log/NotConvertedLog.php b/src/Migration/Logging/Log/NotConvertedLog.php new file mode 100644 index 000000000..064de37f9 --- /dev/null +++ b/src/Migration/Logging/Log/NotConvertedLog.php @@ -0,0 +1,30 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Migration\Logging\Log; + +use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; + +#[Package('after-sales')] +readonly class NotConvertedLog extends AbstractMigrationLogEntry +{ + public function getLevel(): string + { + return self::LOG_LEVEL_INFO; + } + + public function getCode(): string + { + return 'SWAG_MIGRATION__ENTITY_NOT_CONVERTED'; + } + + public function isUserFixable(): bool + { + return false; + } +} diff --git a/src/Migration/Logging/Log/ProcessorNotFoundLog.php b/src/Migration/Logging/Log/ProcessorNotFoundLog.php index 2ade8210d..13f953088 100644 --- a/src/Migration/Logging/Log/ProcessorNotFoundLog.php +++ b/src/Migration/Logging/Log/ProcessorNotFoundLog.php @@ -8,16 +8,14 @@ namespace SwagMigrationAssistant\Migration\Logging\Log; use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; #[Package('fundamentals@after-sales')] -class ProcessorNotFoundLog implements LogEntryInterface +readonly class ProcessorNotFoundLog extends AbstractMigrationLogEntry { - public function __construct( - private readonly string $runId, - private readonly string $entity, - private readonly string $profileName, - private readonly string $gatewayName, - ) { + public function isUserFixable(): bool + { + return false; } public function getLevel(): string @@ -29,63 +27,4 @@ public function getCode(): string { return 'SWAG_MIGRATION__PROCESSOR_NOT_FOUND'; } - - public function getTitle(): string - { - return 'Processor not found'; - } - - /** - * @return array{profileName: string, gatewayName: string, entity: ?string} - */ - public function getParameters(): array - { - return [ - 'profileName' => $this->profileName, - 'gatewayName' => $this->gatewayName, - 'entity' => $this->getEntity(), - ]; - } - - public function getDescription(): string - { - $args = $this->getParameters(); - - return \sprintf( - 'Processor for profile "%s", gateway "%s" and entity "%s" not found.', - $args['profileName'], - $args['gatewayName'], - $args['entity'] - ); - } - - public function getEntity(): ?string - { - return $this->entity; - } - - public function getSourceId(): ?string - { - return null; - } - - public function getRunId(): ?string - { - return $this->runId; - } - - public function getSnippetRoot(): string - { - return 'swag-migration.index.error'; - } - - public function getTitleSnippet(): string - { - return \sprintf('%s.%s.title', $this->getSnippetRoot(), $this->getCode()); - } - - public function getDescriptionSnippet(): string - { - return \sprintf('%s.%s.description', $this->getSnippetRoot(), $this->getCode()); - } } diff --git a/src/Migration/Logging/Log/RunAbortedAutomatically.php b/src/Migration/Logging/Log/RunAbortedAutomatically.php deleted file mode 100644 index 6c05e828e..000000000 --- a/src/Migration/Logging/Log/RunAbortedAutomatically.php +++ /dev/null @@ -1,66 +0,0 @@ - - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace SwagMigrationAssistant\Migration\Logging\Log; - -use Shopware\Core\Framework\Log\Package; -use Shopware\Core\Framework\ShopwareHttpException; - -#[Package('fundamentals@after-sales')] -class RunAbortedAutomatically extends BaseRunLogEntry -{ - public function __construct( - string $runId, - private readonly \Throwable $exception, - ) { - parent::__construct($runId); - } - - public function getLevel(): string - { - return self::LOG_LEVEL_ERROR; - } - - public function getCode(): string - { - return 'SWAG_MIGRATION_RUN_ABORTED_AUTOMATICALLY_EXCEPTION'; - } - - public function getTitle(): string - { - return 'Run was aborted automatically, because too many consecutive exceptions occurred'; - } - - /** - * @return array{exceptionCode: int|string, exceptionMessage: ?string, exceptionFile: string, exceptionLine: int, exceptionTrace: ?string, description: string} - */ - public function getParameters(): array - { - $errorCode = $this->exception->getCode(); - if (\is_subclass_of($this->exception, ShopwareHttpException::class)) { - $errorCode = $this->exception->getErrorCode(); - } - - return [ - 'exceptionCode' => $errorCode, - 'exceptionMessage' => \preg_replace('/[[:^print:]]/', '', $this->exception->getMessage()), - 'exceptionFile' => $this->exception->getFile(), - 'exceptionLine' => $this->exception->getLine(), - 'exceptionTrace' => \preg_replace('/[[:^print:]]/', '', $this->exception->getTraceAsString()), - 'description' => \sprintf( - 'RunId: %s ' . \PHP_EOL . '%s', - $this->getRunId(), - \preg_replace('/[[:^print:]]/', '', $this->exception->getMessage()) - ), - ]; - } - - public function getDescription(): string - { - return $this->getParameters()['description']; - } -} diff --git a/src/Migration/Logging/Log/RunAbortedAutomaticallyLog.php b/src/Migration/Logging/Log/RunAbortedAutomaticallyLog.php new file mode 100644 index 000000000..1f164b736 --- /dev/null +++ b/src/Migration/Logging/Log/RunAbortedAutomaticallyLog.php @@ -0,0 +1,30 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Migration\Logging\Log; + +use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; + +#[Package('fundamentals@after-sales')] +readonly class RunAbortedAutomaticallyLog extends AbstractMigrationLogEntry +{ + public function isUserFixable(): bool + { + return false; + } + + public function getLevel(): string + { + return self::LOG_LEVEL_ERROR; + } + + public function getCode(): string + { + return 'SWAG_MIGRATION_RUN_ABORTED_AUTOMATICALLY_EXCEPTION'; + } +} diff --git a/src/Migration/Logging/Log/TemporaryFileErrorLog.php b/src/Migration/Logging/Log/TemporaryFileErrorLog.php index eb4640485..e24c66b08 100644 --- a/src/Migration/Logging/Log/TemporaryFileErrorLog.php +++ b/src/Migration/Logging/Log/TemporaryFileErrorLog.php @@ -8,16 +8,14 @@ namespace SwagMigrationAssistant\Migration\Logging\Log; use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; #[Package('fundamentals@after-sales')] -class TemporaryFileErrorLog extends BaseRunLogEntry +readonly class TemporaryFileErrorLog extends AbstractMigrationLogEntry { - public function __construct( - string $runId, - string $entity, - ?string $sourceId = null, - ) { - parent::__construct($runId, $entity, $sourceId); + public function isUserFixable(): bool + { + return false; } public function getLevel(): string @@ -29,27 +27,4 @@ public function getCode(): string { return 'SWAG_MIGRATION__TEMPORARY_FILE_COULD_NOT_BE_CREATED'; } - - public function getTitle(): string - { - return 'An exception occurred'; - } - - /** - * @return array{entity: ?string, sourceId: ?string, exceptionCode: int|string, description: string} - */ - public function getParameters(): array - { - return [ - 'entity' => $this->getEntity(), - 'sourceId' => $this->getSourceId(), - 'exceptionCode' => $this->getCode(), - 'description' => 'The temporary file for media download could not be created', - ]; - } - - public function getDescription(): string - { - return $this->getParameters()['description']; - } } diff --git a/src/Migration/Logging/Log/ThemeCompilingErrorRunLog.php b/src/Migration/Logging/Log/ThemeCompilingErrorRunLog.php index 667ba2229..751a30e82 100644 --- a/src/Migration/Logging/Log/ThemeCompilingErrorRunLog.php +++ b/src/Migration/Logging/Log/ThemeCompilingErrorRunLog.php @@ -8,15 +8,14 @@ namespace SwagMigrationAssistant\Migration\Logging\Log; use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; #[Package('fundamentals@after-sales')] -class ThemeCompilingErrorRunLog extends BaseRunLogEntry +readonly class ThemeCompilingErrorRunLog extends AbstractMigrationLogEntry { - public function __construct( - string $runId, - string $sourceId, - ) { - parent::__construct($runId, null, $sourceId); + public function isUserFixable(): bool + { + return false; } public function getLevel(): string @@ -28,29 +27,4 @@ public function getCode(): string { return 'SWAG_MIGRATION__THEME_COMPILING_ERROR'; } - - public function getTitle(): string - { - return 'Theme compiling error'; - } - - /** - * @return array{sourceId: ?string} - */ - public function getParameters(): array - { - return [ - 'sourceId' => $this->getSourceId(), - ]; - } - - public function getDescription(): string - { - $args = $this->getParameters(); - - return \sprintf( - 'The theme with id "%s" could not be compiled.', - $args['sourceId'] - ); - } } diff --git a/src/Migration/Logging/Log/UnknownEntityLog.php b/src/Migration/Logging/Log/UnknownEntityLog.php index 428d3c3c8..a8de064e2 100644 --- a/src/Migration/Logging/Log/UnknownEntityLog.php +++ b/src/Migration/Logging/Log/UnknownEntityLog.php @@ -8,18 +8,14 @@ namespace SwagMigrationAssistant\Migration\Logging\Log; use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; #[Package('fundamentals@after-sales')] -class UnknownEntityLog extends BaseRunLogEntry +readonly class UnknownEntityLog extends AbstractMigrationLogEntry { - public function __construct( - string $runId, - string $entity, - string $sourceId, - private readonly string $requiredForEntity, - private readonly string $requiredForSourceId, - ) { - parent::__construct($runId, $entity, $sourceId); + public function isUserFixable(): bool + { + return false; } public function getLevel(): string @@ -29,57 +25,6 @@ public function getLevel(): string public function getCode(): string { - $entity = $this->getEntity(); - if ($entity === null) { - return 'SWAG_MIGRATION_ENTITY_UNKNOWN'; - } - - return \sprintf('SWAG_MIGRATION_%s_ENTITY_UNKNOWN', \mb_strtoupper($entity)); - } - - public function getTitle(): string - { - $entity = $this->getEntity(); - if ($entity === null) { - return 'Cannot find entity'; - } - - return \sprintf('Cannot find %s', $entity); - } - - /** - * @return array{requiredForEntity: string, requiredForSourceId: string, entity: ?string, sourceId: ?string} - */ - public function getParameters(): array - { - return [ - 'requiredForEntity' => $this->requiredForEntity, - 'requiredForSourceId' => $this->requiredForSourceId, - 'entity' => $this->getEntity(), - 'sourceId' => $this->getSourceId(), - ]; - } - - public function getDescription(): string - { - $args = $this->getParameters(); - - return \sprintf( - 'The %s entity with the source id "%s" cannot find the depended %s entity with the source id "%s".', - $args['requiredForEntity'], - $args['requiredForSourceId'], - $args['entity'], - $args['sourceId'] - ); - } - - public function getTitleSnippet(): string - { - return \sprintf('%s.%s.title', $this->getSnippetRoot(), 'SWAG_MIGRATION_ENTITY_UNKNOWN'); - } - - public function getDescriptionSnippet(): string - { - return \sprintf('%s.%s.description', $this->getSnippetRoot(), 'SWAG_MIGRATION_ENTITY_UNKNOWN'); + return 'SWAG_MIGRATION_ENTITY_UNKNOWN'; } } diff --git a/src/Migration/Logging/Log/UnsupportedObjectType.php b/src/Migration/Logging/Log/UnsupportedObjectType.php deleted file mode 100644 index df34e69b5..000000000 --- a/src/Migration/Logging/Log/UnsupportedObjectType.php +++ /dev/null @@ -1,62 +0,0 @@ - - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace SwagMigrationAssistant\Migration\Logging\Log; - -use Shopware\Core\Framework\Log\Package; - -#[Package('fundamentals@after-sales')] -class UnsupportedObjectType extends BaseRunLogEntry -{ - public function __construct( - string $runId, - private readonly string $type, - string $entity, - string $sourceId, - ) { - parent::__construct($runId, $entity, $sourceId); - } - - public function getLevel(): string - { - return self::LOG_LEVEL_WARNING; - } - - public function getCode(): string - { - return 'SWAG_MIGRATION__SHOPWARE_UNSUPPORTED_OBJECT_TYPE'; - } - - public function getTitle(): string - { - return 'Unsupported object type'; - } - - /** - * @return array{objectType: string, entity: ?string, sourceId: ?string} - */ - public function getParameters(): array - { - return [ - 'objectType' => $this->type, - 'entity' => $this->getEntity(), - 'sourceId' => $this->getSourceId(), - ]; - } - - public function getDescription(): string - { - $args = $this->getParameters(); - - return \sprintf( - '%s of object type "%s" with source id "%s" could not be converted.', - $args['entity'], - $args['objectType'], - $args['sourceId'] - ); - } -} diff --git a/src/Migration/Logging/Log/UnsupportedObjectTypeLog.php b/src/Migration/Logging/Log/UnsupportedObjectTypeLog.php new file mode 100644 index 000000000..1c56bb373 --- /dev/null +++ b/src/Migration/Logging/Log/UnsupportedObjectTypeLog.php @@ -0,0 +1,30 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Migration\Logging\Log; + +use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; + +#[Package('fundamentals@after-sales')] +readonly class UnsupportedObjectTypeLog extends AbstractMigrationLogEntry +{ + public function isUserFixable(): bool + { + return false; + } + + public function getLevel(): string + { + return self::LOG_LEVEL_WARNING; + } + + public function getCode(): string + { + return 'SWAG_MIGRATION__SHOPWARE_UNSUPPORTED_OBJECT_TYPE'; + } +} diff --git a/src/Migration/Logging/Log/WriteExceptionRunLog.php b/src/Migration/Logging/Log/WriteExceptionRunLog.php index 32c192607..b3bded60c 100644 --- a/src/Migration/Logging/Log/WriteExceptionRunLog.php +++ b/src/Migration/Logging/Log/WriteExceptionRunLog.php @@ -8,20 +8,14 @@ namespace SwagMigrationAssistant\Migration\Logging\Log; use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; #[Package('fundamentals@after-sales')] -class WriteExceptionRunLog extends BaseRunLogEntry +readonly class WriteExceptionRunLog extends AbstractMigrationLogEntry { - /** - * @param array $error - */ - public function __construct( - string $runId, - string $entity, - private readonly array $error, - ?string $dataId = null, - ) { - parent::__construct($runId, $entity, $dataId); + public function isUserFixable(): bool + { + return false; } public function getLevel(): string @@ -33,31 +27,4 @@ public function getCode(): string { return 'SWAG_MIGRATION__WRITE_EXCEPTION_OCCURRED'; } - - public function getTitle(): string - { - return 'A write exception has occurred'; - } - - /** - * @return array{entity: ?string, dataId: ?string, error: array, description: string} - */ - public function getParameters(): array - { - return [ - 'entity' => $this->getEntity(), - 'dataId' => $this->getSourceId(), - 'error' => $this->error, - 'description' => (string) \json_encode([ - 'entity' => $this->getEntity(), - 'dataId' => $this->getSourceId(), - 'error' => $this->error, - ], \JSON_PRETTY_PRINT), - ]; - } - - public function getDescription(): string - { - return $this->getParameters()['description']; - } } diff --git a/src/Migration/Logging/LoggingService.php b/src/Migration/Logging/LoggingService.php index 41f14bfaf..f1c22709a 100644 --- a/src/Migration/Logging/LoggingService.php +++ b/src/Migration/Logging/LoggingService.php @@ -11,7 +11,7 @@ use Shopware\Core\Framework\Context; use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository; use Shopware\Core\Framework\Log\Package; -use SwagMigrationAssistant\Migration\Logging\Log\LogEntryInterface; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogEntry; #[Package('fundamentals@after-sales')] class LoggingService implements LoggingServiceInterface @@ -51,22 +51,41 @@ public function saveLogging(Context $context): void } } - public function addLogEntry(LogEntryInterface $logEntry): void + public function addLogEntry(MigrationLogEntry $logEntry): void { $this->logging[] = [ + 'runId' => $logEntry->getRunId(), + 'profileName' => $logEntry->getProfileName(), + 'gatewayName' => $logEntry->getGatewayName(), 'level' => $logEntry->getLevel(), 'code' => $logEntry->getCode(), - 'title' => $logEntry->getTitle(), - 'description' => $logEntry->getDescription(), - 'parameters' => $logEntry->getParameters(), - 'titleSnippet' => $logEntry->getTitleSnippet(), - 'descriptionSnippet' => $logEntry->getDescriptionSnippet(), - 'entity' => $logEntry->getEntity(), - 'sourceId' => $logEntry->getSourceId(), - 'runId' => $logEntry->getRunId(), + 'userFixable' => $logEntry->isUserFixable(), + 'entityId' => $logEntry->getEntityId(), + 'entityName' => $logEntry->getEntityName(), + 'fieldName' => $logEntry->getFieldName(), + 'fieldSourcePath' => $logEntry->getFieldSourcePath(), + 'sourceData' => $logEntry->getSourceData(), + 'convertedData' => $logEntry->getConvertedData(), + 'exceptionMessage' => $logEntry->getExceptionMessage(), + 'exceptionTrace' => $logEntry->getExceptionTrace(), ]; } + /** + * @param array $keys + * @param callable(array-key $key, mixed|null $value): MigrationLogEntry $callback + */ + public function addLogForEach(array $keys, callable $callback): void + { + foreach ($keys as $key => $value) { + if (\array_is_list($keys)) { + $this->addLogEntry($callback($value, null)); + } else { + $this->addLogEntry($callback($key, $value)); + } + } + } + private function writePerEntry(Context $context): void { foreach ($this->logging as $log) { diff --git a/src/Migration/Logging/LoggingServiceInterface.php b/src/Migration/Logging/LoggingServiceInterface.php index 61416a10a..26c30301c 100644 --- a/src/Migration/Logging/LoggingServiceInterface.php +++ b/src/Migration/Logging/LoggingServiceInterface.php @@ -9,12 +9,18 @@ use Shopware\Core\Framework\Context; use Shopware\Core\Framework\Log\Package; -use SwagMigrationAssistant\Migration\Logging\Log\LogEntryInterface; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogEntry; #[Package('fundamentals@after-sales')] interface LoggingServiceInterface { - public function addLogEntry(LogEntryInterface $logEntry): void; + public function addLogEntry(MigrationLogEntry $logEntry): void; + + /** + * @param array $keys + * @param callable(array-key $key, mixed|null $value): MigrationLogEntry $callback + */ + public function addLogForEach(array $keys, callable $callback): void; public function saveLogging(Context $context): void; } diff --git a/src/Migration/Logging/SwagMigrationLoggingDefinition.php b/src/Migration/Logging/SwagMigrationLoggingDefinition.php index 2b4287fac..3831502f0 100644 --- a/src/Migration/Logging/SwagMigrationLoggingDefinition.php +++ b/src/Migration/Logging/SwagMigrationLoggingDefinition.php @@ -9,13 +9,13 @@ use Shopware\Core\Framework\DataAbstractionLayer\EntityDefinition; use Shopware\Core\Framework\DataAbstractionLayer\Field\AutoIncrementField; +use Shopware\Core\Framework\DataAbstractionLayer\Field\BoolField; use Shopware\Core\Framework\DataAbstractionLayer\Field\CreatedAtField; use Shopware\Core\Framework\DataAbstractionLayer\Field\FkField; use Shopware\Core\Framework\DataAbstractionLayer\Field\Flag\PrimaryKey; use Shopware\Core\Framework\DataAbstractionLayer\Field\Flag\Required; use Shopware\Core\Framework\DataAbstractionLayer\Field\IdField; use Shopware\Core\Framework\DataAbstractionLayer\Field\JsonField; -use Shopware\Core\Framework\DataAbstractionLayer\Field\LongTextField; use Shopware\Core\Framework\DataAbstractionLayer\Field\ManyToOneAssociationField; use Shopware\Core\Framework\DataAbstractionLayer\Field\StringField; use Shopware\Core\Framework\DataAbstractionLayer\Field\UpdatedAtField; @@ -47,20 +47,24 @@ protected function defineFields(): FieldCollection { return new FieldCollection([ (new IdField('id', 'id'))->addFlags(new PrimaryKey(), new Required()), + new FkField('run_id', 'runId', SwagMigrationRunDefinition::class), + (new StringField('profile_name', 'profileName', 64))->addFlags(new Required()), + (new StringField('gateway_name', 'gatewayName', 64))->addFlags(new Required()), (new StringField('level', 'level', 64))->addFlags(new Required()), (new StringField('code', 'code'))->addFlags(new Required()), - (new LongTextField('title', 'title'))->addFlags(new Required()), - (new LongTextField('description', 'description'))->addFlags(new Required()), - (new JsonField('parameters', 'parameters'))->addFlags(new Required()), - (new StringField('title_snippet', 'titleSnippet'))->addFlags(new Required()), - (new StringField('description_snippet', 'descriptionSnippet'))->addFlags(new Required()), - new StringField('entity', 'entity'), - new StringField('source_id', 'sourceId'), - new FkField('run_id', 'runId', SwagMigrationRunDefinition::class), + (new BoolField('user_fixable', 'userFixable'))->addFlags(new Required()), + new StringField('entity_name', 'entityName', 64), + new StringField('field_name', 'fieldName', 64), + new StringField('field_source_path', 'fieldSourcePath', 255), + new JsonField('source_data', 'sourceData'), + new JsonField('converted_data', 'convertedData'), + new StringField('exception_message', 'exceptionMessage', 255), + new JsonField('exception_trace', 'exceptionTrace'), + new IdField('entity_id', 'entityId'), + new AutoIncrementField(), new CreatedAtField(), new UpdatedAtField(), new ManyToOneAssociationField('run', 'run_id', SwagMigrationRunDefinition::class), - new AutoIncrementField(), ]); } } diff --git a/src/Migration/Logging/SwagMigrationLoggingEntity.php b/src/Migration/Logging/SwagMigrationLoggingEntity.php index 56727b665..f26a732c9 100644 --- a/src/Migration/Logging/SwagMigrationLoggingEntity.php +++ b/src/Migration/Logging/SwagMigrationLoggingEntity.php @@ -17,29 +17,86 @@ class SwagMigrationLoggingEntity extends Entity { use EntityIdTrait; + protected string $runId; + + protected ?SwagMigrationRunEntity $run = null; + + protected string $profileName; + + protected string $gatewayName; + protected string $level; protected string $code; - protected string $title; + protected bool $userFixable; - protected string $description; + protected int $autoIncrement; - protected array $parameters; + protected ?string $entityName = null; - protected string $titleSnippet; + protected ?string $fieldName = null; - protected string $descriptionSnippet; + protected ?string $fieldSourcePath = null; - protected ?string $entity; + /** + * @var array>|null + */ + protected ?array $sourceData = null; - protected ?string $sourceId; + /** + * @var array>|null + */ + protected ?array $convertedData = null; - protected ?string $runId; + protected ?string $exceptionMessage = null; - protected ?SwagMigrationRunEntity $run; + protected ?string $entityId; - protected int $autoIncrement; + /** + * @var array>|null + */ + protected ?array $exceptionTrace = null; + + public function getRunId(): string + { + return $this->runId; + } + + public function setRunId(string $runId): void + { + $this->runId = $runId; + } + + public function getRun(): ?SwagMigrationRunEntity + { + return $this->run; + } + + public function setRun(SwagMigrationRunEntity $run): void + { + $this->run = $run; + } + + public function getProfileName(): string + { + return $this->profileName; + } + + public function setProfileName(string $profileName): void + { + $this->profileName = $profileName; + } + + public function getGatewayName(): string + { + return $this->gatewayName; + } + + public function setGatewayName(string $gatewayName): void + { + $this->gatewayName = $gatewayName; + } public function getLevel(): string { @@ -61,103 +118,121 @@ public function setCode(string $code): void $this->code = $code; } - public function getTitle(): string + public function isUserFixable(): bool { - return $this->title; + return $this->userFixable; } - public function setTitle(string $title): void + public function setUserFixable(bool $userFixable): void { - $this->title = $title; + $this->userFixable = $userFixable; } - public function getDescription(): string + public function getAutoIncrement(): int { - return $this->description; + return $this->autoIncrement; } - public function setDescription(string $description): void + public function setAutoIncrement(int $autoIncrement): void { - $this->description = $description; + $this->autoIncrement = $autoIncrement; } - public function getParameters(): array + public function getEntityName(): ?string { - return $this->parameters; + return $this->entityName; } - public function setParameters(array $parameters): void + public function setEntityName(string $entityName): void { - $this->parameters = $parameters; + $this->entityName = $entityName; } - public function getTitleSnippet(): string + public function getFieldName(): ?string { - return $this->titleSnippet; + return $this->fieldName; } - public function setTitleSnippet(string $titleSnippet): void + public function setFieldName(string $fieldName): void { - $this->titleSnippet = $titleSnippet; + $this->fieldName = $fieldName; } - public function getDescriptionSnippet(): string + public function getFieldSourcePath(): ?string { - return $this->descriptionSnippet; + return $this->fieldSourcePath; } - public function setDescriptionSnippet(string $descriptionSnippet): void + public function setFieldSourcePath(string $fieldSourcePath): void { - $this->descriptionSnippet = $descriptionSnippet; + $this->fieldSourcePath = $fieldSourcePath; } - public function getEntity(): ?string + /** + * @return array>|null + */ + public function getSourceData(): ?array { - return $this->entity; + return $this->sourceData; } - public function setEntity(?string $entity): void + /** + * @param array> $sourceData + */ + public function setSourceData(array $sourceData): void { - $this->entity = $entity; + $this->sourceData = $sourceData; } - public function getSourceId(): ?string + /** + * @return array>|null + */ + public function getConvertedData(): ?array { - return $this->sourceId; + return $this->convertedData; } - public function setSourceId(?string $sourceId): void + /** + * @param array> $convertedData + */ + public function setConvertedData(array $convertedData): void { - $this->sourceId = $sourceId; + $this->convertedData = $convertedData; } - public function getRunId(): ?string + public function getExceptionMessage(): ?string { - return $this->runId; + return $this->exceptionMessage; } - public function setRunId(?string $runId): void + public function setExceptionMessage(string $exceptionMessage): void { - $this->runId = $runId; + $this->exceptionMessage = $exceptionMessage; } - public function getRun(): ?SwagMigrationRunEntity + /** + * @return array>|null + */ + public function getExceptionTrace(): ?array { - return $this->run; + return $this->exceptionTrace; } - public function setRun(?SwagMigrationRunEntity $run): void + /** + * @param array> $exceptionTrace + */ + public function setExceptionTrace(array $exceptionTrace): void { - $this->run = $run; + $this->exceptionTrace = $exceptionTrace; } - public function getAutoIncrement(): int + public function getEntityId(): ?string { - return $this->autoIncrement; + return $this->entityId; } - public function setAutoIncrement(int $autoIncrement): void + public function setEntityId(?string $entityId): void { - $this->autoIncrement = $autoIncrement; + $this->entityId = $entityId; } } diff --git a/src/Migration/Mapping/MappingService.php b/src/Migration/Mapping/MappingService.php index 3afb1a88c..d84ab7b04 100644 --- a/src/Migration/Mapping/MappingService.php +++ b/src/Migration/Mapping/MappingService.php @@ -17,6 +17,8 @@ use Shopware\Core\Framework\DataAbstractionLayer\Search\EntitySearchResult; use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter; use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter; +use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter; +use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\NotFilter; use Shopware\Core\Framework\DataAbstractionLayer\Write\EntityWriterInterface; use Shopware\Core\Framework\Log\Package; use Shopware\Core\Framework\Uuid\Uuid; @@ -85,7 +87,7 @@ public function getOrCreateMapping( } if ($uuid !== null) { - $mapping['entityUuid'] = $uuid; + $mapping['entityId'] = $uuid; } if ($entityValue !== null) { @@ -118,7 +120,7 @@ public function getMapping( connection_id AS connectionId, entity, old_identifier AS oldIdentifier, - entity_uuid AS entityUuid, + entity_id AS entityId, entity_value AS entityValue, checksum, additional_data AS additionalData @@ -133,7 +135,7 @@ public function getMapping( $mapping['id'] = Uuid::fromBytesToHex($mapping['id']); $mapping['connectionId'] = Uuid::fromBytesToHex($mapping['connectionId']); - $mapping['entityUuid'] = $mapping['entityUuid'] === null ? null : Uuid::fromBytesToHex($mapping['entityUuid']); + $mapping['entityId'] = $mapping['entityId'] === null ? null : Uuid::fromBytesToHex($mapping['entityId']); if (!empty($mapping['additionalData'])) { $mapping['additionalData'] = \json_decode($mapping['additionalData'], true, 512, \JSON_THROW_ON_ERROR); } else { @@ -159,14 +161,14 @@ public function createMapping( ?string $uuid = null, ?string $entityValue = null, ): array { - $fallbackEntityUuid = $entityValue !== null ? null : Uuid::randomHex(); + $fallbackEntityId = $entityValue !== null ? null : Uuid::randomHex(); $mapping = [ 'id' => Uuid::randomHex(), 'connectionId' => $connectionId, 'entity' => $entityName, 'oldIdentifier' => $oldIdentifier, - 'entityUuid' => $uuid ?? $fallbackEntityUuid, + 'entityId' => $uuid ?? $fallbackEntityId, 'entityValue' => $entityValue, 'checksum' => $checksum, 'additionalData' => $additionalData, @@ -192,7 +194,7 @@ public function updateMapping( $oldIdentifier, $updateData['checksum'] ?? null, $updateData['additionalData'] ?? null, - $updateData['entityUuid'] ?? null + $updateData['entityId'] ?? null ); } @@ -212,6 +214,22 @@ public function getMappings(string $connectionId, string $entityName, array $ids return $this->migrationMappingRepo->search($criteria, $context); } + public function hasValidMappingByEntityId(string $connectionId, string $entityName, string $entityId, Context $context): bool + { + $criteria = new Criteria(); + $criteria->addFilter( + new EqualsFilter('connectionId', $connectionId), + new EqualsFilter('entity', $entityName), + new EqualsFilter('entityId', $entityId), + new NotFilter(MultiFilter::CONNECTION_AND, [ + new EqualsFilter('oldIdentifier', null), + ]), + ); + $criteria->setLimit(1); + + return $this->migrationMappingRepo->searchIds($criteria, $context)->getTotal() > 0; + } + public function preloadMappings(array $mappingIds, Context $context): void { if (empty($mappingIds)) { @@ -230,7 +248,7 @@ public function preloadMappings(array $mappingIds, Context $context): void 'connectionId' => $mapping->getConnectionId(), 'entity' => $entityName, 'oldIdentifier' => $oldIdentifier, - 'entityUuid' => $mapping->getEntityUuid(), + 'entityId' => $mapping->getEntityId(), 'entityValue' => $mapping->getEntityValue(), 'checksum' => $mapping->getChecksum(), 'additionalData' => $mapping->getAdditionalData(), @@ -248,12 +266,12 @@ public function getUuidsByEntity(string $connectionId, string $entityName, Conte $entities = $this->migrationMappingRepo->search($criteria, $context)->getEntities(); - $entityUuids = []; + $entityIds = []; foreach ($entities as $entity) { - $entityUuids[] = $entity->getEntityUuid(); + $entityIds[] = $entity->getEntityId(); } - return $entityUuids; + return $entityIds; } public function getValue(string $connectionId, string $entityName, string $oldIdentifier, Context $context): ?string @@ -285,7 +303,7 @@ public function getValue(string $connectionId, string $entityName, string $oldId 'connectionId' => $element->getConnectionId(), 'entity' => $element->getEntity(), 'oldIdentifier' => $element->getOldIdentifier(), - 'entityUuid' => $element->getEntityUuid(), + 'entityId' => $element->getEntityId(), 'entityValue' => $value, 'checksum' => $element->getChecksum(), 'additionalData' => $element->getAdditionalData(), @@ -298,10 +316,10 @@ public function getValue(string $connectionId, string $entityName, string $oldId return null; } - public function deleteMapping(string $entityUuid, string $connectionId, Context $context): void + public function deleteMapping(string $entityId, string $connectionId, Context $context): void { foreach ($this->writeArray as $key => $writeMapping) { - if ($writeMapping['connectionId'] === $connectionId && $writeMapping['entityUuid'] === $entityUuid) { + if ($writeMapping['connectionId'] === $connectionId && $writeMapping['entityId'] === $entityId) { unset($this->writeArray[$key]); $this->writeArray = \array_values($this->writeArray); @@ -310,13 +328,13 @@ public function deleteMapping(string $entityUuid, string $connectionId, Context } foreach ($this->mappings as $hash => $mapping) { - if (isset($mapping['entityUuid']) && $mapping['entityUuid'] === $entityUuid) { + if (isset($mapping['entityId']) && $mapping['entityId'] === $entityId) { unset($this->mappings[$hash]); } } $criteria = new Criteria(); - $criteria->addFilter(new EqualsFilter('entityUuid', $entityUuid)); + $criteria->addFilter(new EqualsFilter('entityId', $entityId)); $criteria->addFilter(new EqualsFilter('connectionId', $connectionId)); $criteria->setLimit(1); @@ -335,12 +353,12 @@ public function writeMapping(): void try { $isFirstInsert = true; - $insertSql = 'INSERT INTO swag_migration_mapping (id, connection_id, entity, old_identifier, entity_uuid, entity_value, checksum, additional_data, created_at) VALUES '; + $insertSql = 'INSERT INTO swag_migration_mapping (id, connection_id, entity, old_identifier, entity_id, entity_value, checksum, additional_data, created_at) VALUES '; $insertParams = []; $updateSql = ' ON DUPLICATE KEY UPDATE entity = VALUES(entity), old_identifier = VALUES(old_identifier), - entity_uuid = VALUES(entity_uuid), + entity_id = VALUES(entity_id), entity_value = VALUES(entity_value), checksum = VALUES(checksum), additional_data = VALUES(additional_data), @@ -352,13 +370,13 @@ public function writeMapping(): void $insertSql .= ', '; } - $insertSql .= \sprintf('(:id%d, :connectionId%d, :entity%d, :oldIdentifier%d, :entityUuid%d, :entityValue%d, :checksum%d, :additionalData%d, :createdAt%d)', $index, $index, $index, $index, $index, $index, $index, $index, $index); + $insertSql .= \sprintf('(:id%d, :connectionId%d, :entity%d, :oldIdentifier%d, :entityId%d, :entityValue%d, :checksum%d, :additionalData%d, :createdAt%d)', $index, $index, $index, $index, $index, $index, $index, $index, $index); $insertParams['id' . $index] = Uuid::fromHexToBytes($writeMapping['id']); $insertParams['connectionId' . $index] = Uuid::fromHexToBytes($writeMapping['connectionId']); $insertParams['entity' . $index] = $writeMapping['entity']; $insertParams['oldIdentifier' . $index] = $writeMapping['oldIdentifier']; - $insertParams['entityUuid' . $index] = $writeMapping['entityUuid'] === null ? null : Uuid::fromHexToBytes($writeMapping['entityUuid']); + $insertParams['entityId' . $index] = $writeMapping['entityId'] === null ? null : Uuid::fromHexToBytes($writeMapping['entityId']); $insertParams['entityValue' . $index] = $writeMapping['entityValue']; $insertParams['checksum' . $index] = $writeMapping['checksum']; $insertParams['additionalData' . $index] = \json_encode($writeMapping['additionalData']); @@ -390,7 +408,7 @@ public function getMigratedSalesChannelUuids(string $connectionId, Context $cont $uuids = []; foreach ($result as $swagMigrationMappingEntity) { - $uuid = $swagMigrationMappingEntity->getEntityUuid(); + $uuid = $swagMigrationMappingEntity->getEntityId(); if ($uuid === null) { continue; @@ -423,12 +441,12 @@ private function writePerEntry(): void { foreach ($this->writeArray as $mapping) { try { - $insertSql = 'INSERT INTO swag_migration_mapping (id, connection_id, entity, old_identifier, entity_uuid, entity_value, checksum, additional_data, created_at) - VALUES (:id, :connectionId, :entity, :oldIdentifier, :entityUuid, :entityValue, :checksum, :additionalData, :createdAt) + $insertSql = 'INSERT INTO swag_migration_mapping (id, connection_id, entity, old_identifier, entity_id, entity_value, checksum, additional_data, created_at) + VALUES (:id, :connectionId, :entity, :oldIdentifier, :entityId, :entityValue, :checksum, :additionalData, :createdAt) ON DUPLICATE KEY UPDATE entity = VALUES(entity), old_identifier = VALUES(old_identifier), - entity_uuid = VALUES(entity_uuid), + entity_id = VALUES(entity_id), entity_value = VALUES(entity_value), checksum = VALUES(checksum), additional_data = VALUES(additional_data), @@ -439,7 +457,7 @@ private function writePerEntry(): void $insertParams['connectionId'] = Uuid::fromHexToBytes($mapping['connectionId']); $insertParams['entity'] = $mapping['entity']; $insertParams['oldIdentifier'] = $mapping['oldIdentifier']; - $insertParams['entityUuid'] = $mapping['entityUuid'] === null ? null : Uuid::fromHexToBytes($mapping['entityUuid']); + $insertParams['entityId'] = $mapping['entityId'] === null ? null : Uuid::fromHexToBytes($mapping['entityId']); $insertParams['entityValue'] = $mapping['entityValue']; $insertParams['checksum'] = $mapping['checksum']; $insertParams['additionalData'] = \json_encode($mapping['additionalData']); diff --git a/src/Migration/Mapping/MappingServiceInterface.php b/src/Migration/Mapping/MappingServiceInterface.php index 200769f5a..20dd09660 100644 --- a/src/Migration/Mapping/MappingServiceInterface.php +++ b/src/Migration/Mapping/MappingServiceInterface.php @@ -12,7 +12,7 @@ use Shopware\Core\Framework\Log\Package; /** - * @phpstan-type MappingStruct array{id: string, connectionId: string, oldIdentifier: ?string, entityUuid: ?string, entityValue: ?string, checksum: ?string, additionalData: ?array} + * @phpstan-type MappingStruct array{id: string, connectionId: string, oldIdentifier: ?string, entityId: ?string, entityValue: ?string, checksum: ?string, additionalData: ?array} */ #[Package('fundamentals@after-sales')] interface MappingServiceInterface @@ -75,7 +75,7 @@ public function updateMapping( */ public function getMigratedSalesChannelUuids(string $connectionId, Context $context): array; - public function deleteMapping(string $entityUuid, string $connectionId, Context $context): void; + public function deleteMapping(string $entityId, string $connectionId, Context $context): void; public function writeMapping(): void; @@ -84,5 +84,7 @@ public function writeMapping(): void; */ public function getMappings(string $connectionId, string $entityName, array $ids, Context $context): EntitySearchResult; + public function hasValidMappingByEntityId(string $connectionId, string $entityName, string $entityId, Context $context): bool; + public function preloadMappings(array $mappingIds, Context $context): void; } diff --git a/src/Migration/Mapping/SwagMigrationMappingDefinition.php b/src/Migration/Mapping/SwagMigrationMappingDefinition.php index dd93e6330..3a52470c2 100644 --- a/src/Migration/Mapping/SwagMigrationMappingDefinition.php +++ b/src/Migration/Mapping/SwagMigrationMappingDefinition.php @@ -38,7 +38,7 @@ public function defineFields(): FieldCollection (new FkField('connection_id', 'connectionId', SwagMigrationConnectionDefinition::class))->addFlags(new Required()), (new StringField('entity', 'entity'))->addFlags(new Required()), new StringField('old_identifier', 'oldIdentifier'), - new IdField('entity_uuid', 'entityUuid'), + new IdField('entity_id', 'entityId'), new StringField('entity_value', 'entityValue'), new StringField('checksum', 'checksum'), new JsonField('additional_data', 'additionalData'), diff --git a/src/Migration/Mapping/SwagMigrationMappingEntity.php b/src/Migration/Mapping/SwagMigrationMappingEntity.php index 37871f5ec..284487165 100644 --- a/src/Migration/Mapping/SwagMigrationMappingEntity.php +++ b/src/Migration/Mapping/SwagMigrationMappingEntity.php @@ -25,7 +25,7 @@ class SwagMigrationMappingEntity extends Entity protected ?string $oldIdentifier; - protected ?string $entityUuid; + protected ?string $entityId; protected ?string $entityValue; @@ -76,14 +76,14 @@ public function setOldIdentifier(string $oldIdentifier): void $this->oldIdentifier = $oldIdentifier; } - public function getEntityUuid(): ?string + public function getEntityId(): ?string { - return $this->entityUuid; + return $this->entityId; } - public function setEntityUuid(string $entityUuid): void + public function setEntityId(string $entityId): void { - $this->entityUuid = $entityUuid; + $this->entityId = $entityId; } public function getEntityValue(): ?string diff --git a/src/Migration/Media/MediaFileProcessorRegistry.php b/src/Migration/Media/MediaFileProcessorRegistry.php index eb2cd770d..44b431fd2 100644 --- a/src/Migration/Media/MediaFileProcessorRegistry.php +++ b/src/Migration/Media/MediaFileProcessorRegistry.php @@ -9,7 +9,6 @@ use Shopware\Core\Framework\Log\Package; use SwagMigrationAssistant\Exception\MigrationException; -use SwagMigrationAssistant\Migration\Connection\SwagMigrationConnectionEntity; use SwagMigrationAssistant\Migration\MigrationContextInterface; #[Package('fundamentals@after-sales')] @@ -34,10 +33,10 @@ public function getProcessor(MigrationContextInterface $migrationContext): Media } $connection = $migrationContext->getConnection(); - if ($connection === null) { - throw MigrationException::entityNotExists(SwagMigrationConnectionEntity::class, $migrationContext->getRunUuid()); - } - throw MigrationException::processorNotFound($connection->getProfileName(), $connection->getGatewayName()); + throw MigrationException::processorNotFound( + $connection->getProfileName(), + $connection->getGatewayName() + ); } } diff --git a/src/Migration/Media/Processor/HttpDownloadServiceBase.php b/src/Migration/Media/Processor/HttpDownloadServiceBase.php index 2f02e92d6..224858cf7 100644 --- a/src/Migration/Media/Processor/HttpDownloadServiceBase.php +++ b/src/Migration/Media/Processor/HttpDownloadServiceBase.php @@ -9,20 +9,22 @@ use Doctrine\DBAL\Connection; use GuzzleHttp\Exception\RequestException; -use GuzzleHttp\Promise; use GuzzleHttp\Promise\PromiseInterface; use GuzzleHttp\Promise\Utils; use Psr\Http\Message\ResponseInterface; use Shopware\Core\Content\Media\File\FileSaver; use Shopware\Core\Content\Media\File\MediaFile; +use Shopware\Core\Content\Media\MediaDefinition; use Shopware\Core\Content\Media\MediaException; use Shopware\Core\Framework\Context; use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository; use Shopware\Core\Framework\DataAbstractionLayer\Exception\InconsistentCriteriaIdsException; use Shopware\Core\Framework\Log\Package; +use Shopware\Core\Framework\Util\Hasher; use Shopware\Core\Framework\Uuid\Uuid; use SwagMigrationAssistant\Exception\MigrationException; use SwagMigrationAssistant\Migration\Gateway\HttpClientInterface; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogBuilder; use SwagMigrationAssistant\Migration\Logging\Log\CannotGetFileRunLog; use SwagMigrationAssistant\Migration\Logging\Log\ExceptionRunLog; use SwagMigrationAssistant\Migration\Logging\Log\TemporaryFileErrorLog; @@ -74,17 +76,21 @@ public function process(MigrationContextInterface $migrationContext, Context $co // prepare http client $client = $this->getHttpClient($migrationContext); if ($client === null) { - $this->loggingService->addLogEntry(new ExceptionRunLog( - $migrationContext->getRunUuid(), - $this->getMediaEntity(), - new \Exception('Http download client can not be constructed.') - )); + $exception = new \Exception('Http download client can not be constructed.'); + + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withExceptionMessage($exception->getMessage()) + ->withExceptionTrace($exception->getTrace()) + ->withEntityName(MediaDefinition::ENTITY_NAME) + ->build(ExceptionRunLog::class) + ); $this->loggingService->saveLogging($context); return $workload; } // Do download requests and store the promises - $promises = $this->doMediaDownloadRequests($media, $mappedWorkload, $client); + $promises = $this->doMediaDownloadRequests($migrationContext, $media, $mappedWorkload, $client); // Wait for the requests to complete, even if some of them fail /** @var array $results */ @@ -117,13 +123,13 @@ function (MediaProcessWorkloadStruct $work) use ($uuid) { if ($work->getErrorCount() > ProcessMediaHandler::MEDIA_ERROR_THRESHOLD) { $failureUuids[] = $uuid; $work->setState(MediaProcessWorkloadStruct::ERROR_STATE); - $this->loggingService->addLogEntry(new CannotGetFileRunLog( - $work->getRunId(), - $this->getMediaEntity(), - $work->getMediaId(), - $work->getAdditionalData()['uri'], - $result['reason'] ?? null - )); + + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withEntityName(MediaDefinition::ENTITY_NAME) + ->withEntityId($uuid) + ->build(CannotGetFileRunLog::class) + ); } continue; @@ -138,11 +144,13 @@ function (MediaProcessWorkloadStruct $work) use ($uuid) { if ($filePath === false) { $failureUuids[] = $uuid; $work->setState(MediaProcessWorkloadStruct::ERROR_STATE); - $this->loggingService->addLogEntry(new TemporaryFileErrorLog( - $work->getRunId(), - $this->getMediaEntity(), - $uuid - )); + + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withEntityName(MediaDefinition::ENTITY_NAME) + ->withEntityId($uuid) + ->build(TemporaryFileErrorLog::class) + ); continue; } @@ -179,12 +187,14 @@ function (MediaProcessWorkloadStruct $work) use ($uuid) { } catch (\Exception $e) { $failureUuids[] = $uuid; $work->setState(MediaProcessWorkloadStruct::ERROR_STATE); - $this->loggingService->addLogEntry(new ExceptionRunLog( - $work->getRunId(), - $this->getMediaEntity(), - $e, - $uuid - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withExceptionMessage($e->getMessage()) + ->withExceptionTrace($e->getTrace()) + ->withEntityName(MediaDefinition::ENTITY_NAME) + ->withEntityId($uuid) + ->build(ExceptionRunLog::class) + ); } finally { // clear up temp data \unlink($filePath); @@ -246,7 +256,7 @@ final protected function getDataSetEntity(MigrationContextInterface $migrationCo * * @return array */ - private function doMediaDownloadRequests(array $media, array &$mappedWorkload, HttpClientInterface $client): array + private function doMediaDownloadRequests(MigrationContextInterface $migrationContext, array $media, array &$mappedWorkload, HttpClientInterface $client): array { $promises = []; foreach ($media as $mediaFile) { @@ -256,7 +266,7 @@ private function doMediaDownloadRequests(array $media, array &$mappedWorkload, H $additionalData['uri'] = $mediaFile['uri']; $mappedWorkload[$uuid]->setAdditionalData($additionalData); - $promise = $this->doNormalDownloadRequest($mappedWorkload[$uuid], $client); + $promise = $this->doNormalDownloadRequest($migrationContext, $mappedWorkload[$uuid], $client); if ($promise !== null) { $promises[$uuid] = $promise; @@ -266,7 +276,7 @@ private function doMediaDownloadRequests(array $media, array &$mappedWorkload, H return $promises; } - private function doNormalDownloadRequest(MediaProcessWorkloadStruct $workload, HttpClientInterface $client): ?PromiseInterface + private function doNormalDownloadRequest(MigrationContextInterface $migrationContext, MediaProcessWorkloadStruct $workload, HttpClientInterface $client): ?PromiseInterface { $additionalData = $workload->getAdditionalData(); @@ -277,12 +287,13 @@ private function doNormalDownloadRequest(MediaProcessWorkloadStruct $workload, H $workload->setState(MediaProcessWorkloadStruct::FINISH_STATE); } catch (\Throwable $exception) { // this should never happen because of Promises, but just in case something is wrong with request construction - $this->loggingService->addLogEntry(new ExceptionRunLog( - $workload->getRunId(), - $this->getMediaEntity(), - $exception, - $workload->getMediaId() - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withExceptionMessage($exception->getMessage()) + ->withExceptionTrace($exception->getTrace()) + ->withEntityName(MediaDefinition::ENTITY_NAME) + ->build(ExceptionRunLog::class) + ); $promise = null; $workload->setErrorCount($workload->getErrorCount() + 1); @@ -296,23 +307,28 @@ private function persistFileToMedia(string $filePath, string $uuid, string $name // determine correct info about the temporary file, except for the $fileExtension (which can be overridden) $fileSize = \filesize($filePath); $mimeType = \mime_content_type($filePath); + if ($fileSize === false || $fileSize === 0 || $mimeType === false) { - $this->loggingService->addLogEntry(new ExceptionRunLog( - $migrationContext->getRunUuid(), - $this->getMediaEntity(), - new \Exception('Downloaded file is empty or could not determine mime type.'), - $uuid - )); + $exception = new \Exception('Downloaded file is empty or could not determine mime type.'); + + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withExceptionMessage($exception->getMessage()) + ->withExceptionTrace($exception->getTrace()) + ->withEntityName(MediaDefinition::ENTITY_NAME) + ->build(ExceptionRunLog::class) + ); return; } - $fileHash = \hash_file('md5', $filePath); + + $fileHash = Hasher::hashFile($filePath); $mediaFile = new MediaFile( $filePath, $mimeType, $fileExtension, $fileSize, - $fileHash === false ? null : $fileHash + $fileHash ); $name = \preg_replace('/[^a-zA-Z0-9_-]+/', '-', \mb_strtolower($name)) ?? $uuid; @@ -331,12 +347,13 @@ private function persistFileToMedia(string $filePath, string $uuid, string $name } elseif (\in_array($mediaException->getErrorCode(), [MediaException::MEDIA_ILLEGAL_FILE_NAME, MediaException::MEDIA_EMPTY_FILE_NAME], true)) { $this->fileSaver->persistFileToMedia($mediaFile, Uuid::randomHex(), $uuid, $context); } else { - $this->loggingService->addLogEntry(new ExceptionRunLog( - $migrationContext->getRunUuid(), - $this->getMediaEntity(), - $mediaException, - $uuid - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withExceptionMessage($mediaException->getMessage()) + ->withExceptionTrace($mediaException->getTrace()) + ->withEntityName(MediaDefinition::ENTITY_NAME) + ->build(ExceptionRunLog::class) + ); } } }); diff --git a/src/Migration/MessageQueue/Handler/MigrationProcessHandler.php b/src/Migration/MessageQueue/Handler/MigrationProcessHandler.php index e6d37f8a5..3d2cea681 100644 --- a/src/Migration/MessageQueue/Handler/MigrationProcessHandler.php +++ b/src/Migration/MessageQueue/Handler/MigrationProcessHandler.php @@ -54,7 +54,7 @@ public function __invoke(MigrationProcessMessage $message): void } $processor = $this->processorRegistry->getProcessor($run->getStep()); - $processor->process($migrationContext, $context, $run, $progress); + $processor?->process($migrationContext, $context, $run, $progress); } private function getCurrentRun(MigrationProcessMessage $message, Context $context): SwagMigrationRunEntity diff --git a/src/Migration/MessageQueue/Handler/MigrationProcessorRegistry.php b/src/Migration/MessageQueue/Handler/MigrationProcessorRegistry.php index 2c11cdcf5..9d70c74c3 100644 --- a/src/Migration/MessageQueue/Handler/MigrationProcessorRegistry.php +++ b/src/Migration/MessageQueue/Handler/MigrationProcessorRegistry.php @@ -25,8 +25,12 @@ public function __construct(private readonly iterable $processors) { } - public function getProcessor(MigrationStep $step): MigrationProcessorInterface + public function getProcessor(MigrationStep $step): ?MigrationProcessorInterface { + if (!$step->needsProcessor()) { + return null; + } + foreach ($this->processors as $processor) { if ($processor->supports($step)) { return $processor; diff --git a/src/Migration/MessageQueue/Handler/ProcessMediaHandler.php b/src/Migration/MessageQueue/Handler/ProcessMediaHandler.php index 6839764c6..5702b5349 100644 --- a/src/Migration/MessageQueue/Handler/ProcessMediaHandler.php +++ b/src/Migration/MessageQueue/Handler/ProcessMediaHandler.php @@ -7,12 +7,14 @@ namespace SwagMigrationAssistant\Migration\MessageQueue\Handler; +use Shopware\Core\Content\Media\MediaDefinition; use Shopware\Core\Framework\Context; use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository; use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria; use Shopware\Core\Framework\Log\Package; use SwagMigrationAssistant\Exception\MigrationException; use SwagMigrationAssistant\Exception\NoConnectionFoundException; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogBuilder; use SwagMigrationAssistant\Migration\Logging\Log\ExceptionRunLog; use SwagMigrationAssistant\Migration\Logging\Log\ProcessorNotFoundLog; use SwagMigrationAssistant\Migration\Logging\LoggingServiceInterface; @@ -83,21 +85,24 @@ public function __invoke(ProcessMediaMessage $message): void $processor = $this->mediaFileProcessorRegistry->getProcessor($migrationContext); $workload = $processor->process($migrationContext, $context, $workload); $this->processFailures($context, $migrationContext, $processor, $workload); - } catch (NoConnectionFoundException $e) { - $this->loggingService->addLogEntry(new ProcessorNotFoundLog( - $message->getRunId(), - $message->getEntityName(), - $connection->getProfileName(), - $connection->getGatewayName() - )); + } catch (NoConnectionFoundException $exception) { + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withExceptionMessage($exception->getMessage()) + ->withExceptionTrace($exception->getTrace()) + ->withEntityName(MediaDefinition::ENTITY_NAME) + ->build(ProcessorNotFoundLog::class) + ); $this->loggingService->saveLogging($context); } catch (\Exception $e) { - $this->loggingService->addLogEntry(new ExceptionRunLog( - $message->getRunId(), - $message->getEntityName(), - $e - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withExceptionMessage($e->getMessage()) + ->withExceptionTrace($e->getTrace()) + ->withEntityName(MediaDefinition::ENTITY_NAME) + ->build(ExceptionRunLog::class) + ); $this->loggingService->saveLogging($context); } diff --git a/src/Migration/MessageQueue/Handler/Processor/AbortingProcessor.php b/src/Migration/MessageQueue/Handler/Processor/AbortingProcessor.php index 467a4c490..011df47bf 100644 --- a/src/Migration/MessageQueue/Handler/Processor/AbortingProcessor.php +++ b/src/Migration/MessageQueue/Handler/Processor/AbortingProcessor.php @@ -10,14 +10,12 @@ use Shopware\Core\Framework\Context; use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository; use Shopware\Core\Framework\Log\Package; -use SwagMigrationAssistant\Exception\MigrationException; use SwagMigrationAssistant\Migration\Data\SwagMigrationDataCollection; use SwagMigrationAssistant\Migration\Media\SwagMigrationMediaFileCollection; -use SwagMigrationAssistant\Migration\MessageQueue\Message\MigrationProcessMessage; +use SwagMigrationAssistant\Migration\MessageQueue\Message\ResetChecksumMessage; use SwagMigrationAssistant\Migration\MigrationContextInterface; use SwagMigrationAssistant\Migration\Run\MigrationProgress; use SwagMigrationAssistant\Migration\Run\MigrationStep; -use SwagMigrationAssistant\Migration\Run\RunServiceInterface; use SwagMigrationAssistant\Migration\Run\RunTransitionServiceInterface; use SwagMigrationAssistant\Migration\Run\SwagMigrationRunCollection; use SwagMigrationAssistant\Migration\Run\SwagMigrationRunEntity; @@ -36,7 +34,6 @@ public function __construct( EntityRepository $migrationDataRepo, EntityRepository $migrationMediaFileRepo, RunTransitionServiceInterface $runTransitionService, - private readonly RunServiceInterface $runService, private readonly MessageBusInterface $bus, ) { parent::__construct( @@ -58,16 +55,14 @@ public function process( SwagMigrationRunEntity $run, MigrationProgress $progress, ): void { - $connection = $migrationContext->getConnection(); - if ($connection === null) { - throw MigrationException::noConnectionFound(); - } - - $this->runService->cleanupMappingChecksums($connection->getId(), $context); - - $this->runTransitionService->forceTransitionToRunStep($migrationContext->getRunUuid(), MigrationStep::CLEANUP); - $progress->setIsAborted(true); - $this->updateProgress($migrationContext->getRunUuid(), $progress, $context); - $this->bus->dispatch(new MigrationProcessMessage($context, $migrationContext->getRunUuid())); + $this->bus->dispatch(new ResetChecksumMessage( + $migrationContext->getConnection()->getId(), + $context, + $run->getId(), + $progress->getCurrentEntity(), + null, + 0, + true // abort flow flag + )); } } diff --git a/src/Migration/MessageQueue/Handler/Processor/AbstractProcessor.php b/src/Migration/MessageQueue/Handler/Processor/AbstractProcessor.php index 6428aef77..837402c2f 100644 --- a/src/Migration/MessageQueue/Handler/Processor/AbstractProcessor.php +++ b/src/Migration/MessageQueue/Handler/Processor/AbstractProcessor.php @@ -63,7 +63,7 @@ protected function changeProgressToNextEntity(SwagMigrationRunEntity $run, Migra if ($nextEntity === null && $run->getStep() === MigrationStep::FETCHING) { $nextEntity = \current($dataSets); - $this->runTransitionService->transitionToRunStep($run->getId(), MigrationStep::WRITING); + $this->runTransitionService->transitionToRunStep($run->getId(), MigrationStep::ERROR_RESOLUTION); $progress->setProgress(0); $progress->setTotal($this->getWriteTotal($context)); } elseif ($nextEntity === null && $run->getStep() === MigrationStep::WRITING) { diff --git a/src/Migration/MessageQueue/Handler/Processor/CleanUpProcessor.php b/src/Migration/MessageQueue/Handler/Processor/CleanUpProcessor.php index 5ebe6ac0e..f6c186d0f 100644 --- a/src/Migration/MessageQueue/Handler/Processor/CleanUpProcessor.php +++ b/src/Migration/MessageQueue/Handler/Processor/CleanUpProcessor.php @@ -9,11 +9,9 @@ use Doctrine\DBAL\Connection; use Shopware\Core\Framework\Context; -use Shopware\Core\Framework\DataAbstractionLayer\Dbal\QueryBuilder; use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository; use Shopware\Core\Framework\Log\Package; use SwagMigrationAssistant\Migration\Data\SwagMigrationDataCollection; -use SwagMigrationAssistant\Migration\Data\SwagMigrationDataDefinition; use SwagMigrationAssistant\Migration\Media\SwagMigrationMediaFileCollection; use SwagMigrationAssistant\Migration\MessageQueue\Message\MigrationProcessMessage; use SwagMigrationAssistant\Migration\MigrationContextInterface; @@ -27,6 +25,8 @@ #[Package('fundamentals@after-sales')] class CleanUpProcessor extends AbstractProcessor { + public const BATCH_SIZE = 250; + /** * @param EntityRepository $migrationRunRepo * @param EntityRepository $migrationDataRepo @@ -37,7 +37,7 @@ public function __construct( EntityRepository $migrationDataRepo, EntityRepository $migrationMediaFileRepo, RunTransitionServiceInterface $runTransitionService, - private readonly Connection $dbalConnection, + private readonly Connection $connection, private readonly MessageBusInterface $bus, ) { parent::__construct( @@ -59,22 +59,51 @@ public function process( SwagMigrationRunEntity $run, MigrationProgress $progress, ): void { - $deleteCount = (int) $this->removeMigrationData(); + if ($progress->getTotal() === 0) { + $progress->setTotal($this->getMigrationDataTotal()); + $progress->setProgress(0); + } + + $deleteCount = $this->removeMigrationData(); + + if ($deleteCount > 0) { + $progress->setProgress( + $progress->getProgress() + $deleteCount + ); + } if ($deleteCount <= 0) { - $this->runTransitionService->transitionToRunStep($migrationContext->getRunUuid(), MigrationStep::INDEXING); + $this->runTransitionService->transitionToRunStep( + $migrationContext->getRunUuid(), + MigrationStep::INDEXING + ); } - $this->updateProgress($migrationContext->getRunUuid(), $progress, $context); - $this->bus->dispatch(new MigrationProcessMessage($context, $migrationContext->getRunUuid())); + $this->updateProgress( + $migrationContext->getRunUuid(), + $progress, + $context + ); + + $this->bus->dispatch(new MigrationProcessMessage( + $context, + $migrationContext->getRunUuid() + )); } - private function removeMigrationData(): int|string + private function removeMigrationData(): int { - return (new QueryBuilder($this->dbalConnection)) - ->delete(SwagMigrationDataDefinition::ENTITY_NAME) - ->andWhere('written = 1') - ->setMaxResults(1000) + return (int) $this->connection->createQueryBuilder() + ->delete('swag_migration_data') + ->setMaxResults(self::BATCH_SIZE) ->executeStatement(); } + + private function getMigrationDataTotal(): int + { + return (int) $this->connection->createQueryBuilder() + ->select('COUNT(id)')->from('swag_migration_data') + ->executeQuery() + ->fetchOne(); + } } diff --git a/src/Migration/MessageQueue/Handler/ResetChecksumHandler.php b/src/Migration/MessageQueue/Handler/ResetChecksumHandler.php new file mode 100644 index 000000000..76618154f --- /dev/null +++ b/src/Migration/MessageQueue/Handler/ResetChecksumHandler.php @@ -0,0 +1,195 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Migration\MessageQueue\Handler; + +use Doctrine\DBAL\Connection; +use Doctrine\DBAL\ParameterType; +use Shopware\Core\Framework\Context; +use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository; +use Shopware\Core\Framework\Log\Package; +use Shopware\Core\Framework\Uuid\Uuid; +use SwagMigrationAssistant\Migration\DataSelection\DefaultEntities; +use SwagMigrationAssistant\Migration\MessageQueue\Message\MigrationProcessMessage; +use SwagMigrationAssistant\Migration\MessageQueue\Message\ResetChecksumMessage; +use SwagMigrationAssistant\Migration\Run\MigrationProgress; +use SwagMigrationAssistant\Migration\Run\MigrationStep; +use SwagMigrationAssistant\Migration\Run\ProgressDataSetCollection; +use SwagMigrationAssistant\Migration\Run\RunTransitionServiceInterface; +use SwagMigrationAssistant\Migration\Run\SwagMigrationRunCollection; +use Symfony\Component\Messenger\Attribute\AsMessageHandler; +use Symfony\Component\Messenger\MessageBusInterface; + +/** + * @internal + */ +#[AsMessageHandler] +#[Package('fundamentals@after-sales')] +final readonly class ResetChecksumHandler +{ + public const BATCH_SIZE = 250; + + /** + * @param EntityRepository $migrationRunRepo + */ + public function __construct( + private Connection $connection, + private MessageBusInterface $messageBus, + private EntityRepository $migrationRunRepo, + private RunTransitionServiceInterface $runTransitionService, + ) { + } + + public function __invoke(ResetChecksumMessage $message): void + { + $connectionId = $message->getConnectionId(); + $totalMappings = $message->getTotalMappings(); + $progress = null; + + if ($totalMappings === null) { + $totalMappings = $this->getTotalMappingsCount($connectionId); + + if ($message->getRunId() !== null && $totalMappings > 0) { + $progress = $this->updateProgress( + $message, + 0, + $totalMappings, + $message->getContext() + ); + } + } + + $affectedRows = $this->resetChecksums($connectionId); + + if ($affectedRows === 0) { + $this->handleCompletion($message, $progress); + + return; + } + + $newProcessedCount = $message->getProcessedMappings() + $affectedRows; + + if ($message->getRunId() !== null) { + $progress = $this->updateProgress( + $message, + $newProcessedCount, + $totalMappings, + $message->getContext() + ); + } + + if ($affectedRows < self::BATCH_SIZE) { + $this->handleCompletion($message, $progress); + + return; + } + + $this->messageBus->dispatch(new ResetChecksumMessage( + $message->getConnectionId(), + $message->getContext(), + $message->getRunId(), + $message->getEntity(), + $totalMappings, + $newProcessedCount, + $message->isPartOfAbort() + )); + } + + private function handleCompletion(ResetChecksumMessage $message, ?MigrationProgress $progress): void + { + $this->clearResettingChecksumsFlag(); + + if (!$message->isPartOfAbort() || $message->getRunId() === null) { + return; + } + + $runId = $message->getRunId(); + $context = $message->getContext(); + + $this->runTransitionService->forceTransitionToRunStep( + $runId, + MigrationStep::CLEANUP + ); + + $finalProgress = new MigrationProgress( + 0, + 0, + $progress?->getDataSets() ?? new ProgressDataSetCollection(), + $message->getEntity() ?? DefaultEntities::RULE, + $progress?->getCurrentEntityProgress() ?? 0 + ); + $finalProgress->setIsAborted(true); + + $this->migrationRunRepo->upsert([ + [ + 'id' => $runId, + 'progress' => $finalProgress->jsonSerialize(), + ], + ], $context); + + $this->messageBus->dispatch(new MigrationProcessMessage( + $context, + $runId + )); + } + + private function resetChecksums(string $connectionId): int + { + return (int) $this->connection->executeStatement( + 'UPDATE swag_migration_mapping + SET checksum = NULL + WHERE checksum IS NOT NULL + AND connection_id = :connectionId + LIMIT :limit', + [ + 'connectionId' => Uuid::fromHexToBytes($connectionId), + 'limit' => self::BATCH_SIZE, + ], + [ + 'connectionId' => ParameterType::BINARY, + 'limit' => ParameterType::INTEGER, + ] + ); + } + + private function getTotalMappingsCount(string $connectionId): int + { + return (int) $this->connection->createQueryBuilder() + ->select('COUNT(m.id)') + ->from('swag_migration_mapping', 'm') + ->where('m.checksum IS NOT NULL') + ->andWhere('m.connection_id = :connectionId') + ->setParameter('connectionId', Uuid::fromHexToBytes($connectionId)) + ->executeQuery() + ->fetchOne(); + } + + private function updateProgress(ResetChecksumMessage $message, int $processed, int $total, Context $context): MigrationProgress + { + $progress = new MigrationProgress( + $processed, + $total, + new ProgressDataSetCollection(), + $message->getEntity() ?? DefaultEntities::RULE, + $processed + ); + + $this->migrationRunRepo->update([[ + 'id' => $message->getRunId(), + 'progress' => $progress->jsonSerialize(), + ]], $context); + + return $progress; + } + + private function clearResettingChecksumsFlag(): void + { + $this->connection->executeStatement( + 'UPDATE swag_migration_general_setting SET `is_resetting_checksums` = 0;' + ); + } +} diff --git a/src/Migration/MessageQueue/Handler/CleanupMigrationHandler.php b/src/Migration/MessageQueue/Handler/TruncateMigrationHandler.php similarity index 53% rename from src/Migration/MessageQueue/Handler/CleanupMigrationHandler.php rename to src/Migration/MessageQueue/Handler/TruncateMigrationHandler.php index 536118b91..79cd8978b 100644 --- a/src/Migration/MessageQueue/Handler/CleanupMigrationHandler.php +++ b/src/Migration/MessageQueue/Handler/TruncateMigrationHandler.php @@ -9,7 +9,7 @@ use Doctrine\DBAL\Connection; use Shopware\Core\Framework\Log\Package; -use SwagMigrationAssistant\Migration\MessageQueue\Message\CleanupMigrationMessage; +use SwagMigrationAssistant\Migration\MessageQueue\Message\TruncateMigrationMessage; use Symfony\Component\Messenger\Attribute\AsMessageHandler; use Symfony\Component\Messenger\MessageBusInterface; @@ -18,15 +18,17 @@ /** * @internal */ -final class CleanupMigrationHandler +final class TruncateMigrationHandler { + private const BATCH_SIZE = 250; + public function __construct( private readonly Connection $connection, private readonly MessageBusInterface $bus, ) { } - public function __invoke(CleanupMigrationMessage $message): void + public function __invoke(TruncateMigrationMessage $message): void { $currentStep = 0; $tablesToReset = [ @@ -38,16 +40,40 @@ public function __invoke(CleanupMigrationMessage $message): void 'swag_migration_connection', ]; - $step = \array_search($message->getTableName(), $tablesToReset, true); + $step = \array_search( + $message->getTableName(), + $tablesToReset, + true + ); + if ($step !== false) { $currentStep = $step; } + $affectedRows = (int) $this->connection->executeStatement( + 'DELETE FROM ' . $tablesToReset[$currentStep] . ' LIMIT ' . self::BATCH_SIZE + ); + + if ($affectedRows >= self::BATCH_SIZE) { + $this->bus->dispatch(new TruncateMigrationMessage( + $tablesToReset[$currentStep] + )); + + return; + } + $nextStep = $currentStep + 1; + if (isset($tablesToReset[$nextStep])) { - $nextMessage = new CleanupMigrationMessage($tablesToReset[$nextStep]); - $this->bus->dispatch($nextMessage); + $this->bus->dispatch(new TruncateMigrationMessage( + $tablesToReset[$nextStep] + )); + + return; } - $this->connection->executeStatement('DELETE FROM ' . $tablesToReset[$currentStep] . ';'); + + $this->connection->executeStatement( + 'UPDATE swag_migration_general_setting SET `is_reset` = 0;' + ); } } diff --git a/src/Migration/MessageQueue/Message/ResetChecksumMessage.php b/src/Migration/MessageQueue/Message/ResetChecksumMessage.php new file mode 100644 index 000000000..94af5c3be --- /dev/null +++ b/src/Migration/MessageQueue/Message/ResetChecksumMessage.php @@ -0,0 +1,62 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Migration\MessageQueue\Message; + +use Shopware\Core\Framework\Context; +use Shopware\Core\Framework\Log\Package; +use Shopware\Core\Framework\MessageQueue\AsyncMessageInterface; + +#[Package('fundamentals@after-sales')] +readonly class ResetChecksumMessage implements AsyncMessageInterface +{ + public function __construct( + private string $connectionId, + private Context $context, + private ?string $runId = null, + private ?string $entity = null, + private ?int $totalMappings = null, + private int $processedMappings = 0, + private bool $isPartOfAbort = false, + ) { + } + + public function getConnectionId(): string + { + return $this->connectionId; + } + + public function getContext(): Context + { + return $this->context; + } + + public function getRunId(): ?string + { + return $this->runId; + } + + public function getEntity(): ?string + { + return $this->entity; + } + + public function getTotalMappings(): ?int + { + return $this->totalMappings; + } + + public function getProcessedMappings(): int + { + return $this->processedMappings; + } + + public function isPartOfAbort(): bool + { + return $this->isPartOfAbort; + } +} diff --git a/src/Migration/MessageQueue/Message/CleanupMigrationMessage.php b/src/Migration/MessageQueue/Message/TruncateMigrationMessage.php similarity index 90% rename from src/Migration/MessageQueue/Message/CleanupMigrationMessage.php rename to src/Migration/MessageQueue/Message/TruncateMigrationMessage.php index db9025c46..864521af8 100644 --- a/src/Migration/MessageQueue/Message/CleanupMigrationMessage.php +++ b/src/Migration/MessageQueue/Message/TruncateMigrationMessage.php @@ -11,7 +11,7 @@ use Shopware\Core\Framework\MessageQueue\AsyncMessageInterface; #[Package('fundamentals@after-sales')] -class CleanupMigrationMessage implements AsyncMessageInterface +class TruncateMigrationMessage implements AsyncMessageInterface { public function __construct(private readonly ?string $tableName = null) { diff --git a/src/Migration/MigrationContext.php b/src/Migration/MigrationContext.php index f82105710..547f63dff 100644 --- a/src/Migration/MigrationContext.php +++ b/src/Migration/MigrationContext.php @@ -9,6 +9,7 @@ use Shopware\Core\Framework\Log\Package; use Shopware\Core\Framework\Struct\Struct; +use SwagMigrationAssistant\Exception\MigrationException; use SwagMigrationAssistant\Migration\Connection\SwagMigrationConnectionEntity; use SwagMigrationAssistant\Migration\DataSelection\DataSet\DataSet; use SwagMigrationAssistant\Migration\Gateway\GatewayInterface; @@ -19,46 +20,55 @@ class MigrationContext extends Struct implements MigrationContextInterface { final public const SOURCE_CONTEXT = 'MIGRATION_CONNECTION_CHECK_FOR_RUNNING_MIGRATION'; - private ProfileInterface $profile; - - private ?SwagMigrationConnectionEntity $connection; - - private string $runUuid; + public function __construct( + private SwagMigrationConnectionEntity $connection, + private ?ProfileInterface $profile = null, + private ?GatewayInterface $gateway = null, + private ?DataSet $dataSet = null, + private readonly string $runUuid = '', + private int $offset = 0, + private int $limit = 0, + ) { + } - private ?DataSet $dataSet; + public function getProfile(): ProfileInterface + { + if ($this->profile === null) { + throw MigrationException::migrationContextPropertyMissing('profile'); + } - private int $offset; + return $this->profile; + } - private int $limit; + public function setProfile(ProfileInterface $profile): void + { + $this->profile = $profile; + } - private GatewayInterface $gateway; + public function getGateway(): GatewayInterface + { + if ($this->gateway === null) { + throw MigrationException::migrationContextPropertyMissing('gateway'); + } - public function __construct( - ProfileInterface $profile, - ?SwagMigrationConnectionEntity $connection = null, - string $runUuid = '', - ?DataSet $dataSet = null, - int $offset = 0, - int $limit = 0, - ) { - $this->profile = $profile; - $this->connection = $connection; - $this->runUuid = $runUuid; - $this->dataSet = $dataSet; - $this->offset = $offset; - $this->limit = $limit; + return $this->gateway; } - public function getProfile(): ProfileInterface + public function setGateway(GatewayInterface $gateway): void { - return $this->profile; + $this->gateway = $gateway; } - public function getConnection(): ?SwagMigrationConnectionEntity + public function getConnection(): SwagMigrationConnectionEntity { return $this->connection; } + public function setConnection(SwagMigrationConnectionEntity $connection): void + { + $this->connection = $connection; + } + public function getRunUuid(): string { return $this->runUuid; @@ -79,18 +89,18 @@ public function getOffset(): int return $this->offset; } - public function getLimit(): int + public function setOffset(int $offset): void { - return $this->limit; + $this->offset = $offset; } - public function getGateway(): GatewayInterface + public function getLimit(): int { - return $this->gateway; + return $this->limit; } - public function setGateway(GatewayInterface $gateway): void + public function setLimit(int $limit): void { - $this->gateway = $gateway; + $this->limit = $limit; } } diff --git a/src/Migration/MigrationContextFactory.php b/src/Migration/MigrationContextFactory.php index db3fe037f..11c7793c0 100644 --- a/src/Migration/MigrationContextFactory.php +++ b/src/Migration/MigrationContextFactory.php @@ -22,18 +22,18 @@ use SwagMigrationAssistant\Migration\Setting\GeneralSettingEntity; #[Package('fundamentals@after-sales')] -class MigrationContextFactory implements MigrationContextFactoryInterface +readonly class MigrationContextFactory implements MigrationContextFactoryInterface { /** * @param EntityRepository $generalSettingRepository * @param EntityRepository $migrationConnectionRepository */ public function __construct( - private readonly ProfileRegistryInterface $profileRegistry, - private readonly GatewayRegistryInterface $gatewayRegistry, - private readonly DataSetRegistryInterface $dataSetRegistry, - private readonly EntityRepository $generalSettingRepository, - private readonly EntityRepository $migrationConnectionRepository, + private ProfileRegistryInterface $profileRegistry, + private GatewayRegistryInterface $gatewayRegistry, + private DataSetRegistryInterface $dataSetRegistry, + private EntityRepository $generalSettingRepository, + private EntityRepository $migrationConnectionRepository, ) { } @@ -44,19 +44,23 @@ public function create( string $entity = '', ): ?MigrationContextInterface { $connection = $run->getConnection(); + if ($connection === null) { return null; } $profile = $this->profileRegistry->getProfile($connection->getProfileName()); + $migrationContext = new MigrationContext( - $profile, $connection, - $run->getId(), + $profile, null, + null, + $run->getId(), $offset, $limit ); + $gateway = $this->gatewayRegistry->getGateway($migrationContext); $migrationContext->setGateway($gateway); @@ -68,25 +72,18 @@ public function create( return $migrationContext; } - public function createByProfileName(string $profileName): MigrationContextInterface - { - $profile = $this->profileRegistry->getProfile($profileName); - - return new MigrationContext( - $profile - ); - } - public function createByConnection( SwagMigrationConnectionEntity $connection, ): MigrationContextInterface { $profile = $this->profileRegistry->getProfile( $connection->getProfileName() ); + $migrationContext = new MigrationContext( + $connection, $profile, - $connection ); + $gateway = $this->gatewayRegistry->getGateway($migrationContext); $migrationContext->setGateway($gateway); @@ -96,6 +93,7 @@ public function createByConnection( public function createBySelectedConnection(Context $context): MigrationContextInterface { $settings = $this->generalSettingRepository->search(new Criteria(), $context)->first(); + if (!$settings instanceof GeneralSettingEntity) { throw MigrationException::entityNotExists(GeneralSettingEntity::class, 'Default'); } @@ -104,9 +102,18 @@ public function createBySelectedConnection(Context $context): MigrationContextIn throw MigrationException::noConnectionIsSelected(); } - $connection = $this->migrationConnectionRepository->search(new Criteria([$settings->getSelectedConnectionId()]), $context)->first(); + $connection = $this->migrationConnectionRepository->search( + new Criteria( + [$settings->getSelectedConnectionId()] + ), + $context + )->first(); + if (!$connection instanceof SwagMigrationConnectionEntity) { - throw MigrationException::entityNotExists(SwagMigrationConnectionEntity::class, $settings->getSelectedConnectionId()); + throw MigrationException::entityNotExists( + SwagMigrationConnectionEntity::class, + $settings->getSelectedConnectionId() + ); } return $this->createByConnection($connection); diff --git a/src/Migration/MigrationContextFactoryInterface.php b/src/Migration/MigrationContextFactoryInterface.php index 234ad85ea..88ed520e9 100644 --- a/src/Migration/MigrationContextFactoryInterface.php +++ b/src/Migration/MigrationContextFactoryInterface.php @@ -17,8 +17,6 @@ interface MigrationContextFactoryInterface { public function create(SwagMigrationRunEntity $run, int $offset = 0, int $limit = 0, string $entity = ''): ?MigrationContextInterface; - public function createByProfileName(string $profileName): MigrationContextInterface; - public function createByConnection(SwagMigrationConnectionEntity $connection): MigrationContextInterface; public function createBySelectedConnection(Context $context): MigrationContextInterface; diff --git a/src/Migration/MigrationContextInterface.php b/src/Migration/MigrationContextInterface.php index 60da42ce4..8acac406d 100644 --- a/src/Migration/MigrationContextInterface.php +++ b/src/Migration/MigrationContextInterface.php @@ -18,7 +18,15 @@ interface MigrationContextInterface { public function getProfile(): ProfileInterface; - public function getConnection(): ?SwagMigrationConnectionEntity; + public function setProfile(ProfileInterface $profile): void; + + public function getGateway(): GatewayInterface; + + public function setGateway(GatewayInterface $gateway): void; + + public function getConnection(): SwagMigrationConnectionEntity; + + public function setConnection(SwagMigrationConnectionEntity $connection): void; public function getRunUuid(): string; @@ -26,9 +34,9 @@ public function getDataSet(): ?DataSet; public function getOffset(): int; - public function getLimit(): int; + public function setOffset(int $offset): void; - public function getGateway(): GatewayInterface; + public function getLimit(): int; - public function setGateway(GatewayInterface $gateway): void; + public function setLimit(int $limit): void; } diff --git a/src/Migration/Premapping/AbstractPremappingReader.php b/src/Migration/Premapping/AbstractPremappingReader.php index a659af993..fdf173cd8 100644 --- a/src/Migration/Premapping/AbstractPremappingReader.php +++ b/src/Migration/Premapping/AbstractPremappingReader.php @@ -20,12 +20,8 @@ abstract class AbstractPremappingReader implements PremappingReaderInterface protected function fillConnectionPremappingDictionary(MigrationContextInterface $migrationContext): void { - $connection = $migrationContext->getConnection(); - if ($connection === null) { - return; - } + $connectionMapping = $migrationContext->getConnection()->getPremapping(); - $connectionMapping = $connection->getPremapping(); if ($connectionMapping === null) { return; } diff --git a/src/Migration/Run/MigrationProgressFieldSerializer.php b/src/Migration/Run/MigrationProgressFieldSerializer.php index 3736d4416..d0b5b9cf7 100644 --- a/src/Migration/Run/MigrationProgressFieldSerializer.php +++ b/src/Migration/Run/MigrationProgressFieldSerializer.php @@ -44,12 +44,15 @@ public function encode( $dataSet = $dataSet->jsonSerialize(); } } + + unset($dataSet); } if (isset($value['dataSets']) && \is_array($value['dataSets'])) { foreach ($value['dataSets'] as &$dataSet) { unset($dataSet['extensions']); } + unset($dataSet); } $data = new KeyValuePair($data->getKey(), $value, $data->isRaw()); diff --git a/src/Migration/Run/MigrationStep.php b/src/Migration/Run/MigrationStep.php index 3e8b900d1..e2070efd6 100644 --- a/src/Migration/Run/MigrationStep.php +++ b/src/Migration/Run/MigrationStep.php @@ -16,6 +16,8 @@ enum MigrationStep: string case FETCHING = 'fetching'; + case ERROR_RESOLUTION = 'error-resolution'; + case WRITING = 'writing'; case MEDIA_PROCESSING = 'media-processing'; @@ -39,4 +41,12 @@ public function isRunning(): bool self::ABORTED, ], true); } + + public function needsProcessor(): bool + { + return !\in_array($this, [ + self::ERROR_RESOLUTION, + self::WAITING_FOR_APPROVE, + ], true); + } } diff --git a/src/Migration/Run/RunService.php b/src/Migration/Run/RunService.php index c007637b1..c052f627c 100644 --- a/src/Migration/Run/RunService.php +++ b/src/Migration/Run/RunService.php @@ -10,20 +10,17 @@ use Doctrine\DBAL\Connection; use Doctrine\DBAL\ParameterType; use Shopware\Core\Framework\Context; -use Shopware\Core\Framework\DataAbstractionLayer\Dbal\QueryBuilder; -use Shopware\Core\Framework\DataAbstractionLayer\EntityDefinition; use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository; use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria; use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter; use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter; use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\NotFilter; -use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting; use Shopware\Core\Framework\Log\Package; use Shopware\Core\Framework\Store\Services\TrackingEventClient; -use Shopware\Core\Framework\Uuid\Uuid; use Shopware\Core\System\SalesChannel\SalesChannelCollection; use Shopware\Core\System\SalesChannel\SalesChannelDefinition; use Shopware\Storefront\Theme\ThemeCollection; +use Shopware\Storefront\Theme\ThemeDefinition; use Shopware\Storefront\Theme\ThemeService; use SwagMigrationAssistant\Exception\MigrationException; use SwagMigrationAssistant\Migration\Connection\SwagMigrationConnectionCollection; @@ -31,11 +28,13 @@ use SwagMigrationAssistant\Migration\DataSelection\DataSelectionCollection; use SwagMigrationAssistant\Migration\DataSelection\DataSelectionRegistryInterface; use SwagMigrationAssistant\Migration\EnvironmentInformation; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogBuilder; use SwagMigrationAssistant\Migration\Logging\Log\ThemeCompilingErrorRunLog; use SwagMigrationAssistant\Migration\Logging\LoggingServiceInterface; use SwagMigrationAssistant\Migration\Mapping\MappingServiceInterface; -use SwagMigrationAssistant\Migration\MessageQueue\Message\CleanupMigrationMessage; use SwagMigrationAssistant\Migration\MessageQueue\Message\MigrationProcessMessage; +use SwagMigrationAssistant\Migration\MessageQueue\Message\ResetChecksumMessage; +use SwagMigrationAssistant\Migration\MessageQueue\Message\TruncateMigrationMessage; use SwagMigrationAssistant\Migration\MigrationContext; use SwagMigrationAssistant\Migration\MigrationContextFactoryInterface; use SwagMigrationAssistant\Migration\MigrationContextInterface; @@ -68,7 +67,6 @@ public function __construct( private readonly EntityRepository $generalSettingRepo, private readonly ThemeService $themeService, private readonly MappingServiceInterface $mappingService, - private readonly EntityDefinition $migrationDataDefinition, private readonly Connection $dbalConnection, private readonly LoggingServiceInterface $loggingService, private readonly TrackingEventClient $trackingEventClient, @@ -85,6 +83,10 @@ public function startMigrationRun(array $dataSelectionIds, Context $context): vo throw MigrationException::migrationIsAlreadyRunning(); } + if ($this->isResettingChecksums()) { + throw MigrationException::checksumResetRunning(); + } + $connection = $this->getCurrentConnection($context); if ($connection === null) { @@ -96,9 +98,6 @@ public function startMigrationRun(array $dataSelectionIds, Context $context): vo } $connectionId = $connection->getId(); - // ToDo: MIG-965 - Check how we could put this into the MQ - $this->cleanupUnwrittenRunDataOfLastInactiveRun($context); - $runUuid = $this->createPlainMigrationRun($connectionId, $context); if ($runUuid === null) { @@ -164,6 +163,7 @@ public function abortMigration(Context $context): void $runId = $run->getId(); $runningSteps = [ MigrationStep::FETCHING->value, + MigrationStep::ERROR_RESOLUTION->value, MigrationStep::WRITING->value, MigrationStep::MEDIA_PROCESSING->value, ]; @@ -177,30 +177,29 @@ public function abortMigration(Context $context): void $this->fireTrackingInformation(self::TRACKING_EVENT_MIGRATION_ABORTED, $runId, $context); } - public function cleanupMappingChecksums(string $connectionUuid, Context $context, bool $resetAll = true): void + public function startCleanupMappingChecksums(string $connectionId, Context $context): void { - $sql = <<connectionRepo->search( + new Criteria([$connectionId]), + $context, + )->getEntities()->first(); + + if ($connection === null) { + throw MigrationException::noConnectionFound(); } - $this->dbalConnection->executeStatement( - $sql, - [$connectionUuid], - [ParameterType::STRING] + $affectedRows = $this->dbalConnection->executeStatement( + 'UPDATE swag_migration_general_setting SET `is_resetting_checksums` = 1 WHERE `is_resetting_checksums` = 0;' ); + + if ($affectedRows === 0) { + throw MigrationException::checksumResetRunning(); + } + + $this->bus->dispatch(new ResetChecksumMessage( + $connectionId, + $context, + )); } public function approveFinishingMigration(Context $context): void @@ -220,14 +219,21 @@ public function approveFinishingMigration(Context $context): void $this->fireTrackingInformation(self::TRACKING_EVENT_MIGRATION_FINISHED, $run->getId(), $context); } - public function cleanupMigrationData(Context $context): void + public function startTruncateMigrationData(Context $context): void { if ($this->isMigrationRunning($context)) { throw MigrationException::migrationIsAlreadyRunning(); } - $this->dbalConnection->executeStatement('UPDATE swag_migration_general_setting SET selected_connection_id = NULL, `is_reset` = 1;'); - $this->bus->dispatch(new CleanupMigrationMessage()); + $affectedRows = $this->dbalConnection->executeStatement( + 'UPDATE swag_migration_general_setting SET selected_connection_id = NULL, `is_reset` = 1 WHERE `is_reset` = 0;' + ); + + if ($affectedRows === 0) { + throw MigrationException::truncatingDataRunning(); + } + + $this->bus->dispatch(new TruncateMigrationMessage()); } public function assignThemeToSalesChannel(string $runUuid, Context $context): void @@ -244,27 +250,54 @@ public function assignThemeToSalesChannel(string $runUuid, Context $context): vo } $connectionId = $connection->getId(); - $salesChannels = $this->getSalesChannels($connectionId, $context); - $defaultTheme = $this->getDefaultTheme($context); + $salesChannelIds = $this->getSalesChannels($connectionId, $context); + $defaultThemeId = $this->getDefaultTheme($context); - if ($defaultTheme === null) { + if ($defaultThemeId === null) { return; } - foreach ($salesChannels as $salesChannel) { + foreach ($salesChannelIds as $salesChannelId) { try { - $this->themeService->assignTheme($defaultTheme, $salesChannel, $context); + $this->themeService->assignTheme($defaultThemeId, $salesChannelId, $context); } catch (\Throwable $exception) { - $this->loggingService->addLogEntry(new ThemeCompilingErrorRunLog( - $runUuid, - $defaultTheme - )); + $this->loggingService->addLogEntry( + (new MigrationLogBuilder( + $runUuid, + $connection->getProfileName(), + $connection->getGatewayName(), + )) + ->withExceptionMessage($exception->getMessage()) + ->withExceptionTrace($exception->getTrace()) + ->withEntityName(ThemeDefinition::ENTITY_NAME) + ->withEntityId($defaultThemeId) + ->build(ThemeCompilingErrorRunLog::class) + ); } } $this->loggingService->saveLogging($context); } + public function resumeAfterFixes(Context $context): void + { + $run = $this->getActiveRun($context); + + if ($run === null) { + throw MigrationException::noRunningMigration(); + } + + $runId = $run->getId(); + + if ($run->getStepValue() !== MigrationStep::ERROR_RESOLUTION->value) { + throw MigrationException::migrationNotInStep($runId, MigrationStep::ERROR_RESOLUTION->value); + } + + $this->runTransitionService->transitionToRunStep($runId, MigrationStep::WRITING); + + $this->bus->dispatch(new MigrationProcessMessage($context, $runId)); + } + /** * @param array $dataSelectionIds */ @@ -301,17 +334,11 @@ private function isMigrationRunning(Context $context): bool return $this->getActiveRun($context) !== null; } - private function getLastInactiveRun(Context $context): ?SwagMigrationRunEntity + private function isResettingChecksums(): bool { - $criteria = new Criteria(); - $criteria->addFilter(new MultiFilter(MultiFilter::CONNECTION_OR, [ - new EqualsFilter('step', MigrationStep::ABORTED->value), - new EqualsFilter('step', MigrationStep::FINISHED->value), - ])); - $criteria->addSorting(new FieldSorting('createdAt', 'DESC')); - $criteria->setLimit(1); - - return $this->migrationRunRepo->search($criteria, $context)->getEntities()->first(); + return (bool) $this->dbalConnection->fetchOne( + 'SELECT is_resetting_checksums FROM swag_migration_general_setting LIMIT 1' + ); } private function fireTrackingInformation(string $eventName, string $runUuid, Context $context): void @@ -543,21 +570,6 @@ private function getDefaultTheme(Context $context): ?string return \reset($ids); } - private function cleanupUnwrittenRunDataOfLastInactiveRun(Context $context): void - { - $lastInactiveRun = $this->getLastInactiveRun($context); - - if ($lastInactiveRun === null) { - return; - } - - $queryBuilder = new QueryBuilder($this->dbalConnection); - $queryBuilder->delete($this->migrationDataDefinition->getEntityName()) - ->andWhere('run_id = :runId') - ->setParameter('runId', Uuid::fromHexToBytes($lastInactiveRun->getId())) - ->executeStatement(); - } - private function updateUnprocessedMediaFiles(string $connectionId, string $runUuid): void { $sql = << FETCHING -> WRITING -> MEDIA_PROCESSING -> CLEANUP -> INDEXING -> WAITING_FOR_APPROVE -> IDLE + * IDLE -> FETCHING -> ERROR_RESOLUTION -> WRITING -> MEDIA_PROCESSING -> CLEANUP -> INDEXING -> WAITING_FOR_APPROVE -> IDLE * * If the migration run is aborted, the steps are as follows: - * IDLE -> [FETCHING || WRITING || MEDIA_PROCESSING] -> ABORTING -> CLEANUP -> INDEXING -> IDLE + * IDLE -> [FETCHING || ERROR_RESOLUTION || WRITING || MEDIA_PROCESSING] -> ABORTING -> CLEANUP -> INDEXING -> IDLE */ public function getRunStatus(Context $context): MigrationState; @@ -34,7 +34,9 @@ public function getRunStatus(Context $context): MigrationState; */ public function abortMigration(Context $context): void; - public function cleanupMappingChecksums(string $connectionUuid, Context $context): void; + public function startCleanupMappingChecksums(string $connectionUuid, Context $context): void; + + public function startTruncateMigrationData(Context $context): void; /** * @param array $dataSelectionIds @@ -50,5 +52,5 @@ public function approveFinishingMigration(Context $context): void; public function assignThemeToSalesChannel(string $runUuid, Context $context): void; - public function cleanupMigrationData(Context $context): void; + public function resumeAfterFixes(Context $context): void; } diff --git a/src/Migration/Service/MediaFileProcessorService.php b/src/Migration/Service/MediaFileProcessorService.php index 09ccc695b..a737f596a 100644 --- a/src/Migration/Service/MediaFileProcessorService.php +++ b/src/Migration/Service/MediaFileProcessorService.php @@ -14,6 +14,7 @@ use SwagMigrationAssistant\Exception\DataSetNotFoundException; use SwagMigrationAssistant\Migration\DataSelection\DataSet\DataSet; use SwagMigrationAssistant\Migration\DataSelection\DataSet\DataSetRegistry; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogBuilder; use SwagMigrationAssistant\Migration\Logging\Log\DataSetNotFoundLog; use SwagMigrationAssistant\Migration\Logging\LoggingService; use SwagMigrationAssistant\Migration\MessageQueue\Message\ProcessMediaMessage; @@ -44,8 +45,8 @@ public function processMediaFiles(MigrationContextInterface $migrationContext, C if ($currentDataSet === null) { try { $currentDataSet = $this->dataSetRegistry->getDataSet($migrationContext, $mediaFile['entity']); - } catch (DataSetNotFoundException $e) { - $this->logDataSetNotFoundException($migrationContext, $mediaFile); + } catch (DataSetNotFoundException $exception) { + $this->logDataSetNotFoundException($migrationContext, $exception); continue; } @@ -58,8 +59,8 @@ public function processMediaFiles(MigrationContextInterface $migrationContext, C $messageMediaUuids = []; $currentCount = 0; $currentDataSet = $this->dataSetRegistry->getDataSet($migrationContext, $mediaFile['entity']); - } catch (DataSetNotFoundException $e) { - $this->logDataSetNotFoundException($migrationContext, $mediaFile); + } catch (DataSetNotFoundException $exception) { + $this->logDataSetNotFoundException($migrationContext, $exception); continue; } @@ -128,26 +129,15 @@ private function addMessageToBus(string $runUuid, Context $context, DataSet $dat $this->messageBus->dispatch($message); } - /** - * @param array $mediaFile - */ private function logDataSetNotFoundException( MigrationContextInterface $migrationContext, - array $mediaFile, + \Throwable $exception, ): void { - $connection = $migrationContext->getConnection(); - - if ($connection === null) { - return; - } - $this->loggingService->addLogEntry( - new DataSetNotFoundLog( - $migrationContext->getRunUuid(), - $mediaFile['entity'], - $mediaFile['id'], - $connection->getProfileName() - ) + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withExceptionMessage($exception->getMessage()) + ->withExceptionTrace($exception->getTrace()) + ->build(DataSetNotFoundLog::class) ); } } diff --git a/src/Migration/Service/MigrationDataConverter.php b/src/Migration/Service/MigrationDataConverter.php index ab6d8cdb4..8f3a39687 100644 --- a/src/Migration/Service/MigrationDataConverter.php +++ b/src/Migration/Service/MigrationDataConverter.php @@ -12,15 +12,20 @@ use Shopware\Core\Framework\DataAbstractionLayer\Write\EntityWriterInterface; use Shopware\Core\Framework\DataAbstractionLayer\Write\WriteContext; use Shopware\Core\Framework\Log\Package; +use Shopware\Core\Framework\Util\Hasher; use SwagMigrationAssistant\Migration\Converter\ConverterInterface; use SwagMigrationAssistant\Migration\Converter\ConverterRegistryInterface; +use SwagMigrationAssistant\Migration\Converter\ConvertStruct; use SwagMigrationAssistant\Migration\DataSelection\DataSet\DataSet; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogBuilder; use SwagMigrationAssistant\Migration\Logging\Log\ExceptionRunLog; +use SwagMigrationAssistant\Migration\Logging\Log\NotConvertedLog; use SwagMigrationAssistant\Migration\Logging\LoggingServiceInterface; use SwagMigrationAssistant\Migration\Mapping\MappingDeltaResult; use SwagMigrationAssistant\Migration\Mapping\MappingServiceInterface; use SwagMigrationAssistant\Migration\Media\MediaFileServiceInterface; use SwagMigrationAssistant\Migration\MigrationContextInterface; +use SwagMigrationAssistant\Migration\Validation\MigrationValidationService; #[Package('fundamentals@after-sales')] class MigrationDataConverter implements MigrationDataConverterInterface @@ -32,6 +37,7 @@ public function __construct( private readonly LoggingServiceInterface $loggingService, private readonly EntityDefinition $dataDefinition, private readonly MappingServiceInterface $mappingService, + private readonly MigrationValidationService $validationService, ) { } @@ -67,11 +73,14 @@ public function convert(array $data, MigrationContextInterface $migrationContext $this->mediaFileService->writeMediaFile($context); } } catch (\Throwable $exception) { - $this->loggingService->addLogEntry(new ExceptionRunLog( - $migrationContext->getRunUuid(), - $dataSet::getEntity(), - $exception - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withExceptionMessage($exception->getMessage()) + ->withExceptionTrace($exception->getTrace()) + ->withEntityName($dataSet::getEntity()) + ->build(ExceptionRunLog::class) + ); + $this->loggingService->saveLogging($context); } } @@ -89,8 +98,27 @@ private function convertData( foreach ($data as $item) { try { $convertStruct = $converter->convert($item, $context, $migrationContext); + if (!$convertStruct instanceof ConvertStruct) { + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withSourceData($item) + ->withEntityName($dataSet::getEntity()) + ->build(NotConvertedLog::class) + ); + + continue; + } + $convertFailureFlag = empty($convertStruct->getConverted()); + $this->validationService->validate( + $migrationContext, + $context, + $convertStruct->getConverted(), + $dataSet::getEntity(), + $item + ); + $createData[] = [ 'entity' => $dataSet::getEntity(), 'runId' => $runUuid, @@ -101,12 +129,14 @@ private function convertData( 'convertFailure' => $convertFailureFlag, ]; } catch (\Throwable $exception) { - $this->loggingService->addLogEntry(new ExceptionRunLog( - $runUuid, - $dataSet::getEntity(), - $exception, - $item['id'] ?? null - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withExceptionMessage($exception->getMessage()) + ->withExceptionTrace($exception->getTrace()) + ->withEntityName($dataSet::getEntity()) + ->withSourceData($item) + ->build(ExceptionRunLog::class) + ); $createData[] = [ 'entity' => $dataSet::getEntity(), @@ -137,17 +167,16 @@ private function filterDeltas(array $data, ConverterInterface $converter, Migrat foreach ($data as $dataSet) { $mappedData[$converter->getSourceIdentifier($dataSet)] = $dataSet; - $checksums[$converter->getSourceIdentifier($dataSet)] = \md5(\serialize($dataSet)); + $checksums[$converter->getSourceIdentifier($dataSet)] = Hasher::hash(\serialize($dataSet)); } - $connection = $migrationContext->getConnection(); $dataSet = $migrationContext->getDataSet(); - if ($connection === null || $dataSet === null) { + if ($dataSet === null) { return new MappingDeltaResult(); } - $connectionId = $connection->getId(); + $connectionId = $migrationContext->getConnection()->getId(); $entity = $dataSet::getEntity(); $result = $this->mappingService->getMappings($connectionId, $entity, \array_keys($checksums), $context); diff --git a/src/Migration/Service/MigrationDataFetcher.php b/src/Migration/Service/MigrationDataFetcher.php index 1bfcf9ea6..be4565177 100644 --- a/src/Migration/Service/MigrationDataFetcher.php +++ b/src/Migration/Service/MigrationDataFetcher.php @@ -11,6 +11,7 @@ use Shopware\Core\Framework\Log\Package; use SwagMigrationAssistant\Migration\EnvironmentInformation; use SwagMigrationAssistant\Migration\Gateway\GatewayRegistryInterface; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogBuilder; use SwagMigrationAssistant\Migration\Logging\Log\ExceptionRunLog; use SwagMigrationAssistant\Migration\Logging\LoggingServiceInterface; use SwagMigrationAssistant\Migration\MigrationContextInterface; @@ -34,11 +35,13 @@ public function fetchData(MigrationContextInterface $migrationContext, Context $ try { return $this->gatewayRegistry->getGateway($migrationContext)->read($migrationContext); } catch (\Throwable $exception) { - $this->loggingService->addLogEntry(new ExceptionRunLog( - $migrationContext->getRunUuid(), - $dataSet::getEntity(), - $exception - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withExceptionMessage($exception->getMessage()) + ->withExceptionTrace($exception->getTrace()) + ->withEntityName($dataSet::getEntity()) + ->build(ExceptionRunLog::class) + ); $this->loggingService->saveLogging($context); } diff --git a/src/Migration/Service/MigrationDataWriter.php b/src/Migration/Service/MigrationDataWriter.php index f64147710..8d93d9404 100644 --- a/src/Migration/Service/MigrationDataWriter.php +++ b/src/Migration/Service/MigrationDataWriter.php @@ -12,6 +12,7 @@ use Shopware\Core\Framework\DataAbstractionLayer\EntityDefinition; use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository; use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria; +use Shopware\Core\Framework\DataAbstractionLayer\Search\EntitySearchResult; use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter; use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting; use Shopware\Core\Framework\DataAbstractionLayer\Write\EntityWriterInterface; @@ -20,6 +21,9 @@ use Shopware\Core\Framework\Log\Package; use SwagMigrationAssistant\Exception\WriterNotFoundException; use SwagMigrationAssistant\Migration\Data\SwagMigrationDataCollection; +use SwagMigrationAssistant\Migration\Data\SwagMigrationDataEntity; +use SwagMigrationAssistant\Migration\ErrorResolution\MigrationErrorResolutionService; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogBuilder; use SwagMigrationAssistant\Migration\Logging\Log\ExceptionRunLog; use SwagMigrationAssistant\Migration\Logging\Log\WriteExceptionRunLog; use SwagMigrationAssistant\Migration\Logging\LoggingServiceInterface; @@ -45,6 +49,7 @@ public function __construct( private readonly LoggingServiceInterface $loggingService, private readonly EntityDefinition $dataDefinition, private readonly EntityRepository $mappingRepo, + private readonly MigrationErrorResolutionService $errorResolutionService, ) { // write / upsert entities only with this single context, // otherwise the migration behaves differently when started in the administration @@ -100,15 +105,21 @@ public function writeData(MigrationContextInterface $migrationContext, Context $ return 0; } + $convertedValues = array_values($converted); + $this->errorResolutionService->applyFixes($convertedValues, $migrationContext->getConnection()->getId(), $migrationContext->getRunUuid()); + try { $currentWriter = $this->writerRegistry->getWriter($dataSet::getEntity()); - $currentWriter->writeData(\array_values($converted), $this->writeContext); + $currentWriter->writeData($convertedValues, $this->writeContext); } catch (WriterNotFoundException $writerNotFoundException) { - $this->loggingService->addLogEntry(new ExceptionRunLog( - $migrationContext->getRunUuid(), - $dataSet::getEntity(), - $writerNotFoundException - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withExceptionMessage($writerNotFoundException->getMessage()) + ->withExceptionTrace($writerNotFoundException->getTrace()) + ->withConvertedData([$converted]) + ->withEntityName($dataSet::getEntity()) + ->build(ExceptionRunLog::class) + ); $this->loggingService->saveLogging($context); foreach ($updateWrittenData as &$data) { @@ -125,11 +136,12 @@ public function writeData(MigrationContextInterface $migrationContext, Context $ $dataSet::getEntity(), $updateWrittenData, $migrationContext, - $context + $context, + $migrationData ); - } catch (\Throwable $exception) { + } catch (\Throwable) { // Worst case: something unknown goes wrong (most likely some foreign key constraint that fails) - $this->writePerEntity($converted, $dataSet::getEntity(), $updateWrittenData, $migrationContext, $context); + $this->writePerEntity($converted, $dataSet::getEntity(), $updateWrittenData, $migrationContext); } finally { // Update written-Flag of the entity in the data table $this->entityWriter->update( @@ -154,6 +166,7 @@ public function writeData(MigrationContextInterface $migrationContext, Context $ /** * @param array $converted * @param array $updateWrittenData + * @param EntitySearchResult $migrationData */ private function handleWriteException( WriteException $exception, @@ -162,6 +175,7 @@ private function handleWriteException( array &$updateWrittenData, MigrationContextInterface $migrationContext, Context $context, + EntitySearchResult $migrationData, ): void { $writeErrors = $this->extractWriteErrorsWithIndex($exception); $currentWriter = $this->writerRegistry->getWriter($entityName); @@ -178,12 +192,21 @@ private function handleWriteException( $updateWrittenData[$dataId]['written'] = false; $updateWrittenData[$dataId]['writeFailure'] = true; - $this->loggingService->addLogEntry(new WriteExceptionRunLog( - $migrationContext->getRunUuid(), - $entityName, - $writeErrors[$index], - $dataId - )); + + $currentData = $migrationData->firstWhere(function (SwagMigrationDataEntity $item) use ($dataId) { + return $item->getId() === $dataId; + }); + + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withExceptionMessage($exception->getMessage()) + ->withExceptionTrace($exception->getTrace()) + ->withEntityName($entityName) + ->withConvertedData($entity) + ->withEntityId($entity['id'] ?? null) + ->withSourceData($currentData?->getRaw() ?? []) + ->build(WriteExceptionRunLog::class) + ); ++$index; } @@ -194,8 +217,8 @@ private function handleWriteException( try { $currentWriter->writeData($newData, $this->writeContext); - } catch (\Throwable $exception) { - $this->writePerEntity($converted, $entityName, $updateWrittenData, $migrationContext, $context); + } catch (\Throwable) { + $this->writePerEntity($converted, $entityName, $updateWrittenData, $migrationContext); } } @@ -227,19 +250,21 @@ private function writePerEntity( string $entityName, array &$updateWrittenData, MigrationContextInterface $migrationContext, - Context $context, ): void { foreach ($converted as $dataId => $entity) { try { $currentWriter = $this->writerRegistry->getWriter($entityName); $currentWriter->writeData([$entity], $this->writeContext); } catch (\Throwable $exception) { - $this->loggingService->addLogEntry(new ExceptionRunLog( - $migrationContext->getRunUuid(), - $entityName, - $exception, - $dataId - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withExceptionMessage($exception->getMessage()) + ->withExceptionTrace($exception->getTrace()) + ->withEntityName($entityName) + ->withConvertedData([$entity]) + ->withEntityId($entity['id'] ?? null) + ->build(ExceptionRunLog::class) + ); $updateWrittenData[$dataId]['written'] = false; $updateWrittenData[$dataId]['writeFailure'] = true; diff --git a/src/Migration/Service/PremappingService.php b/src/Migration/Service/PremappingService.php index 71d5a6f61..fb34741e2 100644 --- a/src/Migration/Service/PremappingService.php +++ b/src/Migration/Service/PremappingService.php @@ -68,10 +68,6 @@ public function writePremapping(Context $context, MigrationContextInterface $mig $connection = $migrationContext->getConnection(); - if ($connection === null) { - return; - } - foreach ($premapping as $item) { $entity = $item['entity']; @@ -118,13 +114,8 @@ public function writePremapping(Context $context, MigrationContextInterface $mig */ private function updateConnectionPremapping(Context $context, MigrationContextInterface $migrationContext, array $premapping): void { - $premapping = $this->updateConnectionPremappingStruct($migrationContext, $premapping); - $connection = $migrationContext->getConnection(); - - if ($connection === null) { - return; - } + $premapping = $this->updateConnectionPremappingStruct($migrationContext, $premapping); $this->connectionRepo->update( [ @@ -144,13 +135,7 @@ private function updateConnectionPremapping(Context $context, MigrationContextIn */ private function updateConnectionPremappingStruct(MigrationContextInterface $migrationContext, array $premapping): array { - $connection = $migrationContext->getConnection(); - - if ($connection === null) { - return []; - } - - $connectionPremapping = $connection->getPremapping(); + $connectionPremapping = $migrationContext->getConnection()->getPremapping(); if ($connectionPremapping === null) { $connectionPremapping = []; diff --git a/src/Migration/Setting/GeneralSettingDefinition.php b/src/Migration/Setting/GeneralSettingDefinition.php index e96767518..d075d466d 100644 --- a/src/Migration/Setting/GeneralSettingDefinition.php +++ b/src/Migration/Setting/GeneralSettingDefinition.php @@ -46,6 +46,7 @@ protected function defineFields(): FieldCollection (new IdField('id', 'id'))->addFlags(new PrimaryKey(), new Required()), new FkField('selected_connection_id', 'selectedConnectionId', SwagMigrationConnectionDefinition::class), new BoolField('is_reset', 'isReset'), + new BoolField('is_resetting_checksums', 'isResettingChecksums'), new CreatedAtField(), new UpdatedAtField(), new ManyToOneAssociationField('selectedConnection', 'selected_connection_id', SwagMigrationConnectionDefinition::class, 'id', true), diff --git a/src/Migration/Setting/GeneralSettingEntity.php b/src/Migration/Setting/GeneralSettingEntity.php index 8497e7baa..43dc70884 100644 --- a/src/Migration/Setting/GeneralSettingEntity.php +++ b/src/Migration/Setting/GeneralSettingEntity.php @@ -23,6 +23,8 @@ class GeneralSettingEntity extends Entity protected bool $isReset; + protected bool $isResettingChecksums = false; + public function getSelectedConnectionId(): ?string { return $this->selectedConnectionId; @@ -52,4 +54,14 @@ public function setIsReset(bool $isReset): void { $this->isReset = $isReset; } + + public function isResettingChecksums(): bool + { + return $this->isResettingChecksums; + } + + public function setIsResettingChecksums(bool $isResettingChecksums): void + { + $this->isResettingChecksums = $isResettingChecksums; + } } diff --git a/src/Migration/Subscriber/MessageQueueSubscriber.php b/src/Migration/Subscriber/MessageQueueSubscriber.php index 1449a6350..0756cca52 100644 --- a/src/Migration/Subscriber/MessageQueueSubscriber.php +++ b/src/Migration/Subscriber/MessageQueueSubscriber.php @@ -11,8 +11,9 @@ use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository; use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria; use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogBuilder; use SwagMigrationAssistant\Migration\Logging\Log\MessageQueueExceptionLog; -use SwagMigrationAssistant\Migration\Logging\Log\RunAbortedAutomatically; +use SwagMigrationAssistant\Migration\Logging\Log\RunAbortedAutomaticallyLog; use SwagMigrationAssistant\Migration\Logging\LoggingServiceInterface; use SwagMigrationAssistant\Migration\MessageQueue\Message\MigrationProcessMessage; use SwagMigrationAssistant\Migration\Run\MigrationProgress; @@ -82,11 +83,22 @@ public function onWorkerMessageFailed(WorkerMessageFailedEvent $event): void return; } + $connection = $run->getConnection(); + /* * Raise exception counter and log the exception */ $progress->raiseExceptionCount(); - $this->loggingService->addLogEntry(new MessageQueueExceptionLog($run->getId(), $event->getThrowable(), $progress->getExceptionCount())); + $this->loggingService->addLogEntry( + (new MigrationLogBuilder( + $run->getId(), + $connection?->getProfileName() ?? 'unknown', + $connection?->getGatewayName() ?? 'unknown' + )) + ->withExceptionMessage($event->getThrowable()->getMessage()) + ->withExceptionTrace($event->getThrowable()->getTrace()) + ->build(MessageQueueExceptionLog::class) + ); /* * Check if run is already in aborting state and failed again there, then set run status to aborted and log the error. @@ -96,7 +108,16 @@ public function onWorkerMessageFailed(WorkerMessageFailedEvent $event): void $progress->setIsAborted(true); $this->updateRun($run->getId(), $progress, $message->getContext()); - $this->loggingService->addLogEntry(new RunAbortedAutomatically($run->getId(), $event->getThrowable())); + $this->loggingService->addLogEntry( + (new MigrationLogBuilder( + $run->getId(), + $connection?->getProfileName() ?? 'unknown', + $connection?->getGatewayName() ?? 'unknown' + )) + ->withExceptionMessage($event->getThrowable()->getMessage()) + ->withExceptionTrace($event->getThrowable()->getTrace()) + ->build(RunAbortedAutomaticallyLog::class) + ); $this->loggingService->saveLogging($message->getContext()); return; diff --git a/src/Migration/Validation/Event/MigrationPostValidationEvent.php b/src/Migration/Validation/Event/MigrationPostValidationEvent.php new file mode 100644 index 000000000..dfb0f26f8 --- /dev/null +++ b/src/Migration/Validation/Event/MigrationPostValidationEvent.php @@ -0,0 +1,32 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Migration\Validation\Event; + +use Shopware\Core\Framework\Context; +use Shopware\Core\Framework\Event\ShopwareEvent; +use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Validation\MigrationValidationContext; +use Symfony\Contracts\EventDispatcher\Event; + +#[Package('fundamentals@after-sales')] +class MigrationPostValidationEvent extends Event implements ShopwareEvent +{ + public function __construct(private readonly MigrationValidationContext $validationContext) + { + } + + public function getValidationContext(): MigrationValidationContext + { + return $this->validationContext; + } + + public function getContext(): Context + { + return $this->validationContext->getContext(); + } +} diff --git a/src/Migration/Validation/Event/MigrationPreValidationEvent.php b/src/Migration/Validation/Event/MigrationPreValidationEvent.php new file mode 100644 index 000000000..7790bf95f --- /dev/null +++ b/src/Migration/Validation/Event/MigrationPreValidationEvent.php @@ -0,0 +1,32 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Migration\Validation\Event; + +use Shopware\Core\Framework\Context; +use Shopware\Core\Framework\Event\ShopwareEvent; +use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Validation\MigrationValidationContext; +use Symfony\Contracts\EventDispatcher\Event; + +#[Package('fundamentals@after-sales')] +class MigrationPreValidationEvent extends Event implements ShopwareEvent +{ + public function __construct(private readonly MigrationValidationContext $validationContext) + { + } + + public function getValidationContext(): MigrationValidationContext + { + return $this->validationContext; + } + + public function getContext(): Context + { + return $this->validationContext->getContext(); + } +} diff --git a/src/Migration/Validation/Log/MigrationValidationExceptionLog.php b/src/Migration/Validation/Log/MigrationValidationExceptionLog.php new file mode 100644 index 000000000..74507d172 --- /dev/null +++ b/src/Migration/Validation/Log/MigrationValidationExceptionLog.php @@ -0,0 +1,30 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Migration\Validation\Log; + +use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; + +#[Package('fundamentals@after-sales')] +readonly class MigrationValidationExceptionLog extends AbstractMigrationLogEntry +{ + public function isUserFixable(): bool + { + return false; + } + + public function getLevel(): string + { + return self::LOG_LEVEL_ERROR; + } + + public function getCode(): string + { + return 'SWAG_MIGRATION_VALIDATION_EXCEPTION'; + } +} diff --git a/src/Migration/Validation/Log/MigrationValidationInvalidFieldValueLog.php b/src/Migration/Validation/Log/MigrationValidationInvalidFieldValueLog.php new file mode 100644 index 000000000..5b5340165 --- /dev/null +++ b/src/Migration/Validation/Log/MigrationValidationInvalidFieldValueLog.php @@ -0,0 +1,30 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Migration\Validation\Log; + +use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; + +#[Package('fundamentals@after-sales')] +readonly class MigrationValidationInvalidFieldValueLog extends AbstractMigrationLogEntry +{ + public function isUserFixable(): bool + { + return true; + } + + public function getLevel(): string + { + return self::LOG_LEVEL_ERROR; + } + + public function getCode(): string + { + return 'SWAG_MIGRATION_VALIDATION_INVALID_FIELD_VALUE'; + } +} diff --git a/src/Migration/Validation/Log/MigrationValidationInvalidForeignKeyLog.php b/src/Migration/Validation/Log/MigrationValidationInvalidForeignKeyLog.php new file mode 100644 index 000000000..bdd2a0ae3 --- /dev/null +++ b/src/Migration/Validation/Log/MigrationValidationInvalidForeignKeyLog.php @@ -0,0 +1,30 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Migration\Validation\Log; + +use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; + +#[Package('fundamentals@after-sales')] +readonly class MigrationValidationInvalidForeignKeyLog extends AbstractMigrationLogEntry +{ + public function isUserFixable(): bool + { + return true; + } + + public function getLevel(): string + { + return self::LOG_LEVEL_WARNING; + } + + public function getCode(): string + { + return 'SWAG_MIGRATION_VALIDATION_INVALID_FOREIGN_KEY'; + } +} diff --git a/src/Migration/Validation/Log/MigrationValidationMissingRequiredFieldLog.php b/src/Migration/Validation/Log/MigrationValidationMissingRequiredFieldLog.php new file mode 100644 index 000000000..ff5909673 --- /dev/null +++ b/src/Migration/Validation/Log/MigrationValidationMissingRequiredFieldLog.php @@ -0,0 +1,30 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Migration\Validation\Log; + +use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; + +#[Package('fundamentals@after-sales')] +readonly class MigrationValidationMissingRequiredFieldLog extends AbstractMigrationLogEntry +{ + public function isUserFixable(): bool + { + return true; + } + + public function getLevel(): string + { + return self::LOG_LEVEL_ERROR; + } + + public function getCode(): string + { + return 'SWAG_MIGRATION_VALIDATION_MISSING_REQUIRED_FIELD'; + } +} diff --git a/src/Migration/Validation/Log/MigrationValidationUnexpectedFieldLog.php b/src/Migration/Validation/Log/MigrationValidationUnexpectedFieldLog.php new file mode 100644 index 000000000..d363bf846 --- /dev/null +++ b/src/Migration/Validation/Log/MigrationValidationUnexpectedFieldLog.php @@ -0,0 +1,30 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Migration\Validation\Log; + +use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; + +#[Package('fundamentals@after-sales')] +readonly class MigrationValidationUnexpectedFieldLog extends AbstractMigrationLogEntry +{ + public function isUserFixable(): bool + { + return true; + } + + public function getLevel(): string + { + return self::LOG_LEVEL_WARNING; + } + + public function getCode(): string + { + return 'SWAG_MIGRATION_VALIDATION_UNEXPECTED_FIELD'; + } +} diff --git a/src/Migration/Validation/MigrationValidationContext.php b/src/Migration/Validation/MigrationValidationContext.php new file mode 100644 index 000000000..81e8f04da --- /dev/null +++ b/src/Migration/Validation/MigrationValidationContext.php @@ -0,0 +1,71 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Migration\Validation; + +use Shopware\Core\Framework\Context; +use Shopware\Core\Framework\DataAbstractionLayer\EntityDefinition; +use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\MigrationContextInterface; + +#[Package('fundamentals@after-sales')] +readonly class MigrationValidationContext +{ + protected MigrationValidationResult $validationResult; + + /** + * @param array $convertedData + * @param array $sourceData + */ + public function __construct( + protected Context $shopwareContext, + protected MigrationContextInterface $migrationContext, + protected EntityDefinition $entityDefinition, + protected array $convertedData, + protected array $sourceData, + ) { + $this->validationResult = new MigrationValidationResult( + $this->entityDefinition->getEntityName(), + ); + } + + public function getContext(): Context + { + return $this->shopwareContext; + } + + public function getMigrationContext(): MigrationContextInterface + { + return $this->migrationContext; + } + + /** + * @return array + */ + public function getConvertedData(): array + { + return $this->convertedData; + } + + /** + * @return array + */ + public function getSourceData(): array + { + return $this->sourceData; + } + + public function getEntityDefinition(): EntityDefinition + { + return $this->entityDefinition; + } + + public function getValidationResult(): MigrationValidationResult + { + return $this->validationResult; + } +} diff --git a/src/Migration/Validation/MigrationValidationResult.php b/src/Migration/Validation/MigrationValidationResult.php new file mode 100644 index 000000000..b8c0315ce --- /dev/null +++ b/src/Migration/Validation/MigrationValidationResult.php @@ -0,0 +1,47 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Migration\Validation; + +use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogEntry; + +#[Package('fundamentals@after-sales')] +class MigrationValidationResult +{ + /** + * @param MigrationLogEntry[] $logs + */ + public function __construct( + private readonly string $entityName, + private array $logs = [], + ) { + } + + public function addLog(MigrationLogEntry $log): void + { + $this->logs[] = $log; + } + + /** + * @return MigrationLogEntry[] + */ + public function getLogs(): array + { + return $this->logs; + } + + public function hasLogs(): bool + { + return \count($this->logs) !== 0; + } + + public function getEntityName(): string + { + return $this->entityName; + } +} diff --git a/src/Migration/Validation/MigrationValidationService.php b/src/Migration/Validation/MigrationValidationService.php new file mode 100644 index 000000000..a6c509373 --- /dev/null +++ b/src/Migration/Validation/MigrationValidationService.php @@ -0,0 +1,252 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Migration\Validation; + +use Shopware\Core\Framework\Context; +use Shopware\Core\Framework\DataAbstractionLayer\DefinitionInstanceRegistry; +use Shopware\Core\Framework\DataAbstractionLayer\Field\Field; +use Shopware\Core\Framework\DataAbstractionLayer\Field\FkField; +use Shopware\Core\Framework\DataAbstractionLayer\Field\Flag\Required; +use Shopware\Core\Framework\DataAbstractionLayer\Write\Command\WriteCommandQueue; +use Shopware\Core\Framework\DataAbstractionLayer\Write\DataStack\KeyValuePair; +use Shopware\Core\Framework\DataAbstractionLayer\Write\EntityExistence; +use Shopware\Core\Framework\DataAbstractionLayer\Write\WriteContext; +use Shopware\Core\Framework\DataAbstractionLayer\Write\WriteParameterBag; +use Shopware\Core\Framework\Log\Package; +use Shopware\Core\Framework\Uuid\Uuid; +use SwagMigrationAssistant\Exception\MigrationException; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogBuilder; +use SwagMigrationAssistant\Migration\Logging\LoggingServiceInterface; +use SwagMigrationAssistant\Migration\Mapping\MappingServiceInterface; +use SwagMigrationAssistant\Migration\MigrationContextInterface; +use SwagMigrationAssistant\Migration\Validation\Event\MigrationPostValidationEvent; +use SwagMigrationAssistant\Migration\Validation\Event\MigrationPreValidationEvent; +use SwagMigrationAssistant\Migration\Validation\Log\MigrationValidationExceptionLog; +use SwagMigrationAssistant\Migration\Validation\Log\MigrationValidationInvalidFieldValueLog; +use SwagMigrationAssistant\Migration\Validation\Log\MigrationValidationInvalidForeignKeyLog; +use SwagMigrationAssistant\Migration\Validation\Log\MigrationValidationMissingRequiredFieldLog; +use SwagMigrationAssistant\Migration\Validation\Log\MigrationValidationUnexpectedFieldLog; +use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; + +#[Package('fundamentals@after-sales')] +readonly class MigrationValidationService +{ + public function __construct( + private DefinitionInstanceRegistry $definitionRegistry, + private EventDispatcherInterface $eventDispatcher, + private LoggingServiceInterface $loggingService, + private MappingServiceInterface $mappingService, + ) { + } + + /** + * @param array|null $convertedEntity + * @param array $sourceData + */ + public function validate( + MigrationContextInterface $migrationContext, + Context $shopwareContext, + ?array $convertedEntity, + string $entityName, + array $sourceData, + ): ?MigrationValidationResult { + if (empty($convertedEntity)) { + return null; + } + + $entityDefinition = $this->definitionRegistry->getByEntityName($entityName); + + $validationContext = new MigrationValidationContext( + $shopwareContext, + $migrationContext, + $entityDefinition, + $convertedEntity, + $sourceData, + ); + + $this->eventDispatcher->dispatch( + new MigrationPreValidationEvent($validationContext), + ); + + try { + $this->validateEntityStructure($validationContext); + $this->validateFields($validationContext); + $this->validateAssociations($validationContext); + } catch (\Throwable $exception) { + $validationContext->getValidationResult()->addLog( + MigrationLogBuilder::fromMigrationContext($validationContext->getMigrationContext()) + ->withEntityName($validationContext->getEntityDefinition()->getEntityName()) + ->withSourceData($validationContext->getSourceData()) + ->withConvertedData($validationContext->getConvertedData()) + ->withExceptionMessage($exception->getMessage()) + ->withExceptionTrace($exception->getTrace()) + ->withEntityId($convertedEntity['id'] ?? null) + ->build(MigrationValidationExceptionLog::class) + ); + } + + $this->eventDispatcher->dispatch( + new MigrationPostValidationEvent($validationContext), + ); + + foreach ($validationContext->getValidationResult()->getLogs() as $log) { + $this->loggingService->addLogEntry($log); + } + + $this->loggingService->saveLogging($validationContext->getContext()); + + return $validationContext->getValidationResult(); + } + + private function validateEntityStructure(MigrationValidationContext $validationContext): void + { + $fields = $validationContext->getEntityDefinition()->getFields(); + + $requiredFields = array_values(array_map( + static fn (Field $field) => $field->getPropertyName(), + $fields->filterByFlag(Required::class)->getElements() + )); + + $convertedFieldNames = array_keys($validationContext->getConvertedData()); + $missingRequiredFields = array_diff($requiredFields, $convertedFieldNames); + + foreach ($missingRequiredFields as $missingField) { + $validationContext->getValidationResult()->addLog( + MigrationLogBuilder::fromMigrationContext($validationContext->getMigrationContext()) + ->withEntityName($validationContext->getEntityDefinition()->getEntityName()) + ->withFieldName($missingField) + ->withConvertedData($validationContext->getConvertedData()) + ->withEntityId($validationContext->getConvertedData()['id'] ?? null) + ->build(MigrationValidationMissingRequiredFieldLog::class) + ); + } + + $unexpectedFields = array_diff($convertedFieldNames, array_keys($fields->getElements())); + + foreach ($unexpectedFields as $unexpectedField) { + $validationContext->getValidationResult()->addLog( + MigrationLogBuilder::fromMigrationContext($validationContext->getMigrationContext()) + ->withEntityName($validationContext->getEntityDefinition()->getEntityName()) + ->withFieldName($unexpectedField) + ->withConvertedData($validationContext->getConvertedData()) + ->withEntityId($validationContext->getConvertedData()['id'] ?? null) + ->build(MigrationValidationUnexpectedFieldLog::class) + ); + } + } + + private function validateFields(MigrationValidationContext $validationContext): void + { + $fields = $validationContext->getEntityDefinition()->getFields(); + + if (!isset($validationContext->getConvertedData()['id'])) { + throw MigrationException::unexpectedNullValue('id'); + } + + if (!Uuid::isValid($validationContext->getConvertedData()['id'])) { + throw MigrationException::invalidId($validationContext->getConvertedData()['id'], $validationContext->getEntityDefinition()->getEntityName()); + } + + $entityExistence = EntityExistence::createForEntity( + $validationContext->getEntityDefinition()->getEntityName(), + ['id' => $validationContext->getConvertedData()['id']], + ); + + $parameters = new WriteParameterBag( + $validationContext->getEntityDefinition(), + WriteContext::createFromContext($validationContext->getContext()), + '', + new WriteCommandQueue(), + ); + + foreach ($validationContext->getConvertedData() as $fieldName => $value) { + if (!$fields->has($fieldName)) { + continue; + } + + $field = clone $fields->get($fieldName); + $field->setFlags(new Required()); + + $keyValue = new KeyValuePair( + $field->getPropertyName(), + $value, + true + ); + + try { + $serializer = $field->getSerializer(); + \iterator_to_array($serializer->encode($field, $entityExistence, $keyValue, $parameters), false); + } catch (\Throwable $e) { + $validationContext->getValidationResult()->addLog( + MigrationLogBuilder::fromMigrationContext($validationContext->getMigrationContext()) + ->withEntityName($validationContext->getEntityDefinition()->getEntityName()) + ->withFieldName($fieldName) + ->withConvertedData([$fieldName => $value]) + ->withSourceData($validationContext->getSourceData()) + ->withExceptionMessage($e->getMessage()) + ->withExceptionTrace($e->getTrace()) + ->withEntityId($validationContext->getConvertedData()['id'] ?? null) + ->build(MigrationValidationInvalidFieldValueLog::class) + ); + } + } + } + + private function validateAssociations(MigrationValidationContext $validationContext): void + { + $fields = $validationContext->getEntityDefinition()->getFields(); + + $fkFields = array_values(array_map( + static fn (Field $field) => $field->getPropertyName(), + $fields->filterInstance(FkField::class)->getElements() + )); + + foreach ($fkFields as $fkFieldName) { + if (!isset($validationContext->getConvertedData()[$fkFieldName])) { + continue; + } + + $fkValue = $validationContext->getConvertedData()[$fkFieldName]; + + if ($fkValue === '') { + continue; + } + + $fkField = $fields->get($fkFieldName); + + if (!$fkField instanceof FkField) { + throw MigrationException::unexpectedNullValue($fkFieldName); + } + + $referenceEntity = $fkField->getReferenceEntity(); + + if (!$referenceEntity) { + throw MigrationException::unexpectedNullValue($fkFieldName); + } + + $hasMapping = $this->mappingService->hasValidMappingByEntityId( + $validationContext->getMigrationContext()->getConnection()->getId(), + $referenceEntity, + $fkValue, + $validationContext->getContext() + ); + + if (!$hasMapping) { + $validationContext->getValidationResult()->addLog( + MigrationLogBuilder::fromMigrationContext($validationContext->getMigrationContext()) + ->withEntityName($validationContext->getEntityDefinition()->getEntityName()) + ->withFieldName($fkFieldName) + ->withConvertedData([$fkFieldName => $fkValue]) + ->withSourceData($validationContext->getSourceData()) + ->withEntityId($validationContext->getConvertedData()['id'] ?? null) + ->build(MigrationValidationInvalidForeignKeyLog::class) + ); + } + } + } +} diff --git a/src/Profile/Shopware/Converter/AttributeConverter.php b/src/Profile/Shopware/Converter/AttributeConverter.php index 629301665..c236ce1ea 100644 --- a/src/Profile/Shopware/Converter/AttributeConverter.php +++ b/src/Profile/Shopware/Converter/AttributeConverter.php @@ -39,12 +39,8 @@ public function convert(array $data, Context $context, MigrationContextInterface $converted = []; $connection = $migrationContext->getConnection(); - $this->connectionId = ''; - $this->connectionName = ''; - if ($connection !== null) { - $this->connectionId = $connection->getId(); - $this->connectionName = $connection->getName(); - } + $this->connectionId = $connection->getId(); + $this->connectionName = $connection->getName(); $mapping = $this->mappingService->getOrCreateMapping( $this->connectionId, @@ -52,7 +48,7 @@ public function convert(array $data, Context $context, MigrationContextInterface $this->getCustomFieldEntityName() . 'CustomFieldSet', $context ); - $converted['id'] = $mapping['entityUuid']; + $converted['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $connectionName = ConnectionNameSanitizer::sanitize($this->connectionName); @@ -74,7 +70,7 @@ public function convert(array $data, Context $context, MigrationContextInterface $converted['relations'] = [ [ - 'id' => $mapping['entityUuid'], + 'id' => $mapping['entityId'], 'entityName' => $this->getCustomFieldEntityName(), ], ]; @@ -95,7 +91,7 @@ public function convert(array $data, Context $context, MigrationContextInterface $converted['customFields'] = [ [ - 'id' => $this->mainMapping['entityUuid'], + 'id' => $this->mainMapping['entityId'], 'name' => $converted['name'] . '_' . $data['name'], 'type' => $this->getCustomFieldType($data), 'config' => $this->getCustomFieldConfiguration($data), diff --git a/src/Profile/Shopware/Converter/CategoryConverter.php b/src/Profile/Shopware/Converter/CategoryConverter.php index 95edfc0c3..dfacd188a 100644 --- a/src/Profile/Shopware/Converter/CategoryConverter.php +++ b/src/Profile/Shopware/Converter/CategoryConverter.php @@ -14,7 +14,6 @@ use SwagMigrationAssistant\Exception\MigrationException; use SwagMigrationAssistant\Migration\Converter\ConvertStruct; use SwagMigrationAssistant\Migration\DataSelection\DefaultEntities; -use SwagMigrationAssistant\Migration\Logging\Log\EmptyNecessaryFieldRunLog; use SwagMigrationAssistant\Migration\Logging\LoggingServiceInterface; use SwagMigrationAssistant\Migration\Mapping\Lookup\DefaultCmsPageLookup; use SwagMigrationAssistant\Migration\Mapping\Lookup\LanguageLookup; @@ -36,7 +35,7 @@ abstract class CategoryConverter extends ShopwareConverter protected string $oldCategoryId; - protected string $locale; + protected ?string $locale = null; protected string $runId; @@ -80,25 +79,16 @@ public function convert( $this->migrationContext = $migrationContext; $connection = $migrationContext->getConnection(); - $this->connectionId = ''; - $this->connectionName = ''; - if ($connection !== null) { - $this->connectionId = $connection->getId(); - $this->connectionName = $connection->getName(); - } + $this->connectionId = $connection->getId(); + $this->connectionName = $connection->getName(); - if (!isset($data['_locale'])) { - $this->loggingService->addLogEntry(new EmptyNecessaryFieldRunLog( - $migrationContext->getRunUuid(), - DefaultEntities::CATEGORY, - $this->oldCategoryId, - 'locale' - )); + $converted = []; - return new ConvertStruct(null, $data); + if (isset($data['_locale'])) { + $this->locale = $data['_locale']; + } else { + $this->locale = null; } - $this->locale = $data['_locale']; - $converted = []; $cmsPageUuid = $this->defaultCmsPageLookup->get($context); if ($cmsPageUuid !== null) { @@ -117,7 +107,7 @@ public function convert( throw MigrationException::parentEntityForChildNotFound(DefaultEntities::CATEGORY, $this->oldCategoryId); } $this->mappingIds[] = $parentMapping['id']; - $converted['parentId'] = $parentMapping['entityUuid']; + $converted['parentId'] = $parentMapping['entityId']; unset($parentMapping); // get last root category as previous sibling } elseif (!isset($data['previousSiblingId'])) { @@ -137,7 +127,7 @@ public function convert( ); if ($previousSiblingMapping !== null) { - $converted['afterCategoryId'] = $previousSiblingMapping['entityUuid']; + $converted['afterCategoryId'] = $previousSiblingMapping['entityId']; $this->mappingIds[] = $previousSiblingMapping['id']; } } @@ -151,7 +141,7 @@ public function convert( $this->checksum ); - $converted['id'] = $this->mainMapping['entityUuid']; + $converted['id'] = $this->mainMapping['entityId']; unset($data['id']); $this->convertValue($converted, 'description', $data, 'cmstext', self::TYPE_STRING); @@ -246,8 +236,7 @@ protected function setGivenCategoryTranslation(array &$data, array &$converted): } $locale = $language->getLocale(); - - if ($locale === null || $locale->getCode() === $data['_locale']) { + if (!isset($data['_locale']) || $locale?->getCode() === $data['_locale']) { return; } @@ -262,7 +251,7 @@ protected function setGivenCategoryTranslation(array &$data, array &$converted): $this->oldCategoryId . ':' . $data['_locale'], $this->context ); - $localeTranslation['id'] = $mapping['entityUuid']; + $localeTranslation['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; try { @@ -299,7 +288,7 @@ protected function getCategoryMedia(array $media): array ); $categoryMedia = []; - $categoryMedia['id'] = $mapping['entityUuid']; + $categoryMedia['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; if (empty($media['name'])) { @@ -329,7 +318,7 @@ protected function getCategoryMedia(array $media): array ); if ($albumMapping !== null) { - $categoryMedia['mediaFolderId'] = $albumMapping['entityUuid']; + $categoryMedia['mediaFolderId'] = $albumMapping['entityId']; $this->mappingIds[] = $albumMapping['id']; } @@ -363,13 +352,15 @@ protected function addMediaTranslation(array &$media, array $data): void $data['media']['id'] . ':' . $this->locale, $this->context ); - $localeTranslation['id'] = $mapping['entityUuid']; + $localeTranslation['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; - $languageUuid = $this->languageLookup->get($this->locale, $this->context); - if ($languageUuid !== null) { - $localeTranslation['languageId'] = $languageUuid; - $media['translations'][$languageUuid] = $localeTranslation; + if ($this->locale !== null) { + $languageUuid = $this->languageLookup->get($this->locale, $this->context); + if ($languageUuid !== null) { + $localeTranslation['languageId'] = $languageUuid; + $media['translations'][$languageUuid] = $localeTranslation; + } } } } diff --git a/src/Profile/Shopware/Converter/CrossSellingConverter.php b/src/Profile/Shopware/Converter/CrossSellingConverter.php index 07c487f00..d4e202570 100644 --- a/src/Profile/Shopware/Converter/CrossSellingConverter.php +++ b/src/Profile/Shopware/Converter/CrossSellingConverter.php @@ -11,7 +11,6 @@ use Shopware\Core\Framework\Log\Package; use SwagMigrationAssistant\Migration\Converter\ConvertStruct; use SwagMigrationAssistant\Migration\DataSelection\DefaultEntities; -use SwagMigrationAssistant\Migration\Logging\Log\AssociationRequiredMissingLog; use SwagMigrationAssistant\Migration\MigrationContextInterface; #[Package('fundamentals@after-sales')] @@ -35,10 +34,7 @@ public function convert(array $data, Context $context, MigrationContextInterface $this->runId = $migrationContext->getRunUuid(); $connection = $migrationContext->getConnection(); - $this->connectionId = ''; - if ($connection !== null) { - $this->connectionId = $connection->getId(); - } + $this->connectionId = $connection->getId(); $converted = []; $this->mainMapping = $this->mappingService->getOrCreateMapping( @@ -57,33 +53,17 @@ public function convert(array $data, Context $context, MigrationContextInterface $this->checksum ); - $converted['id'] = $crossSellingMapping['entityUuid']; + $converted['id'] = $crossSellingMapping['entityId']; $sourceProductMapping = $this->getProductMapping($data['articleID']); - if ($sourceProductMapping === null) { - $this->loggingService->addLogEntry(new AssociationRequiredMissingLog( - $this->runId, - DefaultEntities::PRODUCT, - $data['articleID'], - $data['type'] - )); - - return new ConvertStruct(null, $data); + if ($sourceProductMapping !== null) { + $this->mappingIds[] = $sourceProductMapping['id']; } - $this->mappingIds[] = $sourceProductMapping['id']; $relatedProductMapping = $this->getProductMapping($data['relatedarticle']); - if ($relatedProductMapping === null) { - $this->loggingService->addLogEntry(new AssociationRequiredMissingLog( - $this->runId, - DefaultEntities::PRODUCT, - $data['relatedarticle'], - $data['type'] - )); - - return new ConvertStruct(null, $data); + if ($relatedProductMapping !== null) { + $this->mappingIds[] = $relatedProductMapping['id']; } - $this->mappingIds[] = $relatedProductMapping['id']; if ($data['type'] === DefaultEntities::CROSS_SELLING_SIMILAR) { $converted['name'] = 'Similar Items'; @@ -100,15 +80,17 @@ public function convert(array $data, Context $context, MigrationContextInterface $converted['type'] = 'productList'; $converted['active'] = true; - $converted['productId'] = $sourceProductMapping['entityUuid']; $converted['assignedProducts'] = [ [ - 'id' => $relationMapping['entityUuid'], - 'position' => $data['position'], - 'productId' => $relatedProductMapping['entityUuid'], + 'id' => $relationMapping['entityId'] ?? null, + 'position' => $data['position'] ?? null, + 'productId' => $relatedProductMapping['entityId'] ?? null, ], ]; + if (isset($sourceProductMapping['entityId'])) { + $converted['productId'] = $sourceProductMapping['entityId']; + } unset( $data['type'], $data['id'], diff --git a/src/Profile/Shopware/Converter/CurrencyConverter.php b/src/Profile/Shopware/Converter/CurrencyConverter.php index 46fb4df64..5ec5d92f6 100644 --- a/src/Profile/Shopware/Converter/CurrencyConverter.php +++ b/src/Profile/Shopware/Converter/CurrencyConverter.php @@ -40,17 +40,14 @@ public function getSourceIdentifier(array $data): string return $data['currency']; } - public function convert(array $data, Context $context, MigrationContextInterface $migrationContext): ConvertStruct + public function convert(array $data, Context $context, MigrationContextInterface $migrationContext): ?ConvertStruct { $this->generateChecksum($data); $this->context = $context; $this->mainLocale = $data['_locale']; $connection = $migrationContext->getConnection(); - $this->connectionId = ''; - if ($connection !== null) { - $this->connectionId = $connection->getId(); - } + $this->connectionId = $connection->getId(); $currencyUuid = $this->currencyLookup->get($data['currency'], $context); if ($currencyUuid !== null) { @@ -66,7 +63,7 @@ public function convert(array $data, Context $context, MigrationContextInterface ); } - return new ConvertStruct(null, $data); + return null; } $converted = []; @@ -77,7 +74,7 @@ public function convert(array $data, Context $context, MigrationContextInterface $context, $this->checksum ); - $converted['id'] = $this->mainMapping['entityUuid']; + $converted['id'] = $this->mainMapping['entityId']; $converted['isDefault'] = false; unset($data['standard']); @@ -137,7 +134,7 @@ protected function getCurrencyTranslation(array &$currency, array $data): void $data['id'] . ':' . $this->mainLocale, $this->context ); - $localeTranslation['id'] = $mapping['entityUuid']; + $localeTranslation['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $languageUuid = $this->languageLookup->get($this->mainLocale, $this->context); diff --git a/src/Profile/Shopware/Converter/CustomerConverter.php b/src/Profile/Shopware/Converter/CustomerConverter.php index 8698774eb..6964e59d8 100644 --- a/src/Profile/Shopware/Converter/CustomerConverter.php +++ b/src/Profile/Shopware/Converter/CustomerConverter.php @@ -7,6 +7,8 @@ namespace SwagMigrationAssistant\Profile\Shopware\Converter; +use Shopware\Core\Checkout\Customer\Aggregate\CustomerAddress\CustomerAddressDefinition; +use Shopware\Core\Checkout\Customer\CustomerDefinition; use Shopware\Core\Checkout\Customer\CustomerEntity; use Shopware\Core\Defaults; use Shopware\Core\Framework\Context; @@ -17,6 +19,7 @@ use Shopware\Core\System\SalesChannel\SalesChannelCollection; use SwagMigrationAssistant\Migration\Converter\ConvertStruct; use SwagMigrationAssistant\Migration\DataSelection\DefaultEntities; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogBuilder; use SwagMigrationAssistant\Migration\Logging\Log\EmptyNecessaryFieldRunLog; use SwagMigrationAssistant\Migration\Logging\Log\FieldReassignedRunLog; use SwagMigrationAssistant\Migration\Logging\Log\UnknownEntityLog; @@ -26,10 +29,8 @@ use SwagMigrationAssistant\Migration\Mapping\Lookup\LanguageLookup; use SwagMigrationAssistant\Migration\Mapping\MappingServiceInterface; use SwagMigrationAssistant\Migration\MigrationContextInterface; -use SwagMigrationAssistant\Profile\Shopware\Logging\Log\InvalidEmailAddressLog; use SwagMigrationAssistant\Profile\Shopware\Premapping\PaymentMethodReader; use SwagMigrationAssistant\Profile\Shopware\Premapping\SalutationReader; -use Symfony\Component\Validator\Constraints\Email; use Symfony\Component\Validator\Validator\ValidatorInterface; #[Package('fundamentals@after-sales')] @@ -45,17 +46,6 @@ abstract class CustomerConverter extends ShopwareConverter protected string $runId; - /** - * @var list - */ - protected array $requiredDataFieldKeys = [ - 'firstname', - 'lastname', - 'email', - 'salutation', - 'customerGroupId', - ]; - /** * @var list */ @@ -96,46 +86,17 @@ public function convert( MigrationContextInterface $migrationContext, ): ConvertStruct { $this->generateChecksum($data); - $oldData = $data; $this->runId = $migrationContext->getRunUuid(); $this->migrationContext = $migrationContext; - $fields = $this->checkForEmptyRequiredDataFields($data, $this->requiredDataFieldKeys); - - if (!empty($fields)) { - $this->loggingService->addLogEntry(new EmptyNecessaryFieldRunLog( - $this->runId, - DefaultEntities::CUSTOMER, - $data['id'], - \implode(',', $fields) - )); - - return new ConvertStruct(null, $oldData); - } - - if (!$this->checkEmailValidity($data['email'])) { - $this->loggingService->addLogEntry(new InvalidEmailAddressLog( - $this->runId, - DefaultEntities::CUSTOMER, - $data['id'], - $data['email'] - )); - - return new ConvertStruct(null, $oldData); - } + $connection = $migrationContext->getConnection(); + $this->connectionId = $connection->getId(); + $this->connectionName = $connection->getName(); $this->context = $context; $this->mainLocale = $data['_locale']; unset($data['_locale']); - $connection = $migrationContext->getConnection(); - $this->connectionId = ''; - $this->connectionName = ''; - if ($connection !== null) { - $this->connectionId = $connection->getId(); - $this->connectionName = $connection->getName(); - } - $this->mainMapping = $this->mappingService->getOrCreateMapping( $this->connectionId, DefaultEntities::CUSTOMER, @@ -147,7 +108,7 @@ public function convert( $this->oldCustomerId = $data['id']; $converted = []; - $converted['id'] = $this->mainMapping['entityUuid']; + $converted['id'] = $this->mainMapping['entityId']; unset($data['id']); @@ -159,13 +120,13 @@ public function convert( $this->context ); - if (isset($mapping['entityUuid'])) { - $converted['salesChannelId'] = $mapping['entityUuid']; + if (isset($mapping['entityId'])) { + $converted['salesChannelId'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; unset($data['subshopID']); if (isset($data['shop']['customer_scope']) && (bool) $data['shop']['customer_scope'] === true) { - $converted['boundSalesChannelId'] = $mapping['entityUuid']; + $converted['boundSalesChannelId'] = $mapping['entityId']; } } } @@ -203,28 +164,28 @@ public function convert( $converted['customerNumber'] = 'number-' . $this->oldCustomerId; } - $mapping = $this->mappingService->getMapping( - $this->connectionId, - DefaultEntities::CUSTOMER_GROUP, - $data['customerGroupId'], - $context - ); - if ($mapping === null) { - return new ConvertStruct(null, $oldData); + if (isset($data['customerGroupId'])) { + $mapping = $this->mappingService->getMapping( + $this->connectionId, + DefaultEntities::CUSTOMER_GROUP, + $data['customerGroupId'], + $context + ); + if ($mapping !== null) { + $converted['groupId'] = $mapping['entityId']; + $this->mappingIds[] = $mapping['id']; + } + unset($data['customerGroupId'], $data['customergroup']); } - $converted['groupId'] = $mapping['entityUuid']; - $this->mappingIds[] = $mapping['id']; - unset($data['customerGroupId'], $data['customergroup']); if (isset($data['defaultpayment']['id'])) { $defaultPaymentMethodUuid = $this->getDefaultPaymentMethod($data['defaultpayment']); - if ($defaultPaymentMethodUuid === null) { - return new ConvertStruct(null, $oldData); + if ($defaultPaymentMethodUuid !== null) { + $converted['defaultPaymentMethodId'] = $defaultPaymentMethodUuid; } - - $converted['defaultPaymentMethodId'] = $defaultPaymentMethodUuid; } + unset($data['defaultpayment'], $data['paymentpreset']); if (!isset($converted['defaultPaymentMethodId'])) { @@ -235,28 +196,19 @@ public function convert( $this->context ); - if ($mapping === null) { - $this->loggingService->addLogEntry(new EmptyNecessaryFieldRunLog( - $this->runId, - DefaultEntities::CUSTOMER, - $this->oldCustomerId, - 'defaultpayment' - )); - - return new ConvertStruct(null, $oldData); + if ($mapping !== null) { + $converted['defaultPaymentMethodId'] = $mapping['entityId']; + $this->mappingIds[] = $mapping['id']; } - $converted['defaultPaymentMethodId'] = $mapping['entityUuid']; - $this->mappingIds[] = $mapping['id']; } $salutationUuid = $this->getSalutation($data['salutation']); - if ($salutationUuid === null) { - return new ConvertStruct(null, $oldData); + if ($salutationUuid !== null) { + $converted['salutationId'] = $salutationUuid; } - $converted['salutationId'] = $salutationUuid; - if (isset($data['addresses']) && isset($this->mainMapping['entityUuid'])) { - $this->applyAddresses($data, $converted, $this->mainMapping['entityUuid']); + if (isset($data['addresses']) && isset($this->mainMapping['entityId'])) { + $this->applyAddresses($data, $converted, $this->mainMapping['entityId']); } if (isset($data['attributes'])) { @@ -295,19 +247,6 @@ public function convert( $returnData = null; } - if (!isset($converted['defaultBillingAddressId'], $converted['defaultShippingAddressId'])) { - $this->mappingService->deleteMapping($converted['id'], $this->connectionId, $this->context); - - $this->loggingService->addLogEntry(new EmptyNecessaryFieldRunLog( - $this->runId, - DefaultEntities::CUSTOMER, - $this->oldCustomerId, - 'address data' - )); - - return new ConvertStruct(null, $oldData); - } - $this->updateMainMapping($migrationContext, $context); return new ConvertStruct($converted, $returnData, $this->mainMapping['id'] ?? null); @@ -345,19 +284,20 @@ protected function getDefaultPaymentMethod(array $originalData): ?string ); if ($paymentMethodMapping === null) { - $this->loggingService->addLogEntry(new UnknownEntityLog( - $this->runId, - DefaultEntities::PAYMENT_METHOD, - $originalData['id'], - DefaultEntities::CUSTOMER, - $this->oldCustomerId - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(CustomerDefinition::ENTITY_NAME) + ->withFieldName('defaultPaymentMethodId') + ->withFieldSourcePath('default_payment_method') + ->withSourceData($originalData) + ->build(UnknownEntityLog::class) + ); return null; } $this->mappingIds[] = $paymentMethodMapping['id']; - return $paymentMethodMapping['entityUuid']; + return $paymentMethodMapping['entityId']; } /** @@ -373,12 +313,14 @@ protected function applyAddresses(array &$originalData, array &$converted, strin $fields = $this->checkForEmptyRequiredDataFields($address, $this->requiredAddressDataFieldKeys); if (!empty($fields)) { - $this->loggingService->addLogEntry(new EmptyNecessaryFieldRunLog( - $this->runId, - DefaultEntities::CUSTOMER_ADDRESS, - $address['id'], - \implode(',', $fields) - )); + $this->loggingService->addLogForEach( + $fields, + fn (string $key) => MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(CustomerAddressDefinition::ENTITY_NAME) + ->withFieldSourcePath($key) + ->withSourceData($address) + ->build(EmptyNecessaryFieldRunLog::class) + ); continue; } @@ -394,7 +336,7 @@ protected function applyAddresses(array &$originalData, array &$converted, strin $address['id'], $this->context ); - $newAddress['id'] = $addressMapping['entityUuid']; + $newAddress['id'] = $addressMapping['entityId']; $this->mappingIds[] = $addressMapping['id']; $newAddress['salutationId'] = $salutationUuid; @@ -414,11 +356,11 @@ protected function applyAddresses(array &$originalData, array &$converted, strin } } - if (!isset($this->mainMapping['entityUuid'])) { + if (!isset($this->mainMapping['entityId'])) { continue; } - $newAddress['customerId'] = $this->mainMapping['entityUuid']; + $newAddress['customerId'] = $this->mainMapping['entityId']; $newAddress['country'] = $this->getCountry($address['country']); $countryState = $this->getCountryState($address, $newAddress['country']['id']); @@ -456,13 +398,13 @@ protected function applyAddresses(array &$originalData, array &$converted, strin $converted['addresses'] = $addresses; // No valid default billing and shipping address was converted, so use the first valid one as default - $this->checkUnsetDefaultShippingAndDefaultBillingAddress($originalData, $converted, $customerUuid, $addresses); + $this->checkUnsetDefaultShippingAndDefaultBillingAddress($originalData, $converted, $addresses); // No valid default shipping address was converted, but the default billing address is valid - $this->checkUnsetDefaultShippingAddress($originalData, $converted, $customerUuid); + $this->checkUnsetDefaultShippingAddress($originalData, $converted); // No valid default billing address was converted, but the default shipping address is valid - $this->checkUnsetDefaultBillingAddress($originalData, $converted, $customerUuid); + $this->checkUnsetDefaultBillingAddress($originalData, $converted); } /** @@ -487,7 +429,7 @@ protected function getCountry(array $oldCountryData): array $oldCountryData['id'], $this->context ); - $country['id'] = $mapping['entityUuid']; + $country['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; } @@ -533,7 +475,7 @@ protected function applyCountryTranslation(array &$country, array $data): void $data['id'] . ':' . $this->mainLocale, $this->context ); - $localeTranslation['id'] = $mapping['entityUuid']; + $localeTranslation['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $languageUuid = $this->languageLookup->get($this->mainLocale, $this->context); @@ -558,13 +500,12 @@ protected function getCountryState(array $oldAddressData, string $newCountryId): if (!isset($oldAddressData['state_id'], $oldAddressData['country']['countryiso'], $oldAddressData['state']['shortcode'])) { $this->loggingService->addLogEntry( - new UnknownEntityLog( - $this->runId, - DefaultEntities::COUNTRY_STATE, - $oldAddressData['state_id'] ?? 'unknown', - DefaultEntities::CUSTOMER, - $this->oldCustomerId - ) + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(CustomerAddressDefinition::ENTITY_NAME) + ->withFieldName('stateId') + ->withFieldSourcePath('state_id') + ->withSourceData($oldAddressData) + ->build(UnknownEntityLog::class) ); return []; @@ -596,19 +537,18 @@ protected function getCountryState(array $oldAddressData, string $newCountryId): $oldAddressData['state']['active'] )) { $this->loggingService->addLogEntry( - new UnknownEntityLog( - $this->runId, - DefaultEntities::COUNTRY_STATE, - $oldAddressData['state_id'], - DefaultEntities::CUSTOMER, - $this->oldCustomerId - ) + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(CustomerAddressDefinition::ENTITY_NAME) + ->withFieldName('stateId') + ->withFieldSourcePath('state.name') + ->withSourceData($oldAddressData['state']) + ->build(UnknownEntityLog::class) ); return []; } - $state['id'] = $mapping['entityUuid']; + $state['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $oldStateData = $oldAddressData['state']; @@ -649,7 +589,7 @@ protected function applyCountryStateTranslation(array &$state, array $data): voi $data['id'] . ':' . $this->mainLocale, $this->context ); - $localeTranslation['id'] = $mapping['entityUuid']; + $localeTranslation['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $languageUuid = $this->languageLookup->get($this->mainLocale, $this->context); @@ -664,20 +604,25 @@ protected function applyCountryStateTranslation(array &$state, array $data): voi * @param array $converted * @param array> $addresses */ - protected function checkUnsetDefaultShippingAndDefaultBillingAddress(array &$originalData, array &$converted, string $customerUuid, array $addresses): void + protected function checkUnsetDefaultShippingAndDefaultBillingAddress(array &$originalData, array &$converted, array $addresses): void { if (!isset($converted['defaultBillingAddressId']) && !isset($converted['defaultShippingAddressId'])) { $converted['defaultBillingAddressId'] = $addresses[0]['id']; $converted['defaultShippingAddressId'] = $addresses[0]['id']; unset($originalData['default_billing_address_id'], $originalData['default_shipping_address_id']); - $this->loggingService->addLogEntry(new FieldReassignedRunLog( - $this->runId, - DefaultEntities::CUSTOMER, - $customerUuid, - 'default billing and shipping address', - 'first address' - )); + $this->loggingService->addLogForEach( + [ + 'defaultBillingAddressId' => 'default_billing_address_id', + 'defaultShippingAddressId' => 'default_shipping_address_id', + ], + fn (string $key, string $value) => MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(CustomerAddressDefinition::ENTITY_NAME) + ->withFieldName($key) + ->withFieldSourcePath($value) + ->withSourceData($originalData) + ->build(FieldReassignedRunLog::class) + ); } } @@ -685,19 +630,20 @@ protected function checkUnsetDefaultShippingAndDefaultBillingAddress(array &$ori * @param array $originalData * @param array $converted */ - protected function checkUnsetDefaultShippingAddress(array &$originalData, array &$converted, string $customerUuid): void + protected function checkUnsetDefaultShippingAddress(array &$originalData, array &$converted): void { if (!isset($converted['defaultShippingAddressId']) && isset($converted['defaultBillingAddressId'])) { $converted['defaultShippingAddressId'] = $converted['defaultBillingAddressId']; unset($originalData['default_shipping_address_id']); - $this->loggingService->addLogEntry(new FieldReassignedRunLog( - $this->runId, - DefaultEntities::CUSTOMER, - $customerUuid, - 'default shipping address', - 'default billing address' - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(CustomerAddressDefinition::ENTITY_NAME) + ->withFieldName('defaultShippingAddressId') + ->withFieldSourcePath('default_shipping_address_id') + ->withSourceData($originalData) + ->build(FieldReassignedRunLog::class) + ); } } @@ -705,19 +651,20 @@ protected function checkUnsetDefaultShippingAddress(array &$originalData, array * @param array $originalData * @param array $converted */ - protected function checkUnsetDefaultBillingAddress(array &$originalData, array &$converted, string $customerUuid): void + protected function checkUnsetDefaultBillingAddress(array &$originalData, array &$converted): void { if (!isset($converted['defaultBillingAddressId']) && isset($converted['defaultShippingAddressId'])) { $converted['defaultBillingAddressId'] = $converted['defaultShippingAddressId']; unset($originalData['default_billing_address_id']); - $this->loggingService->addLogEntry(new FieldReassignedRunLog( - $this->runId, - DefaultEntities::CUSTOMER, - $customerUuid, - 'default billing address', - 'default shipping address' - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(CustomerAddressDefinition::ENTITY_NAME) + ->withFieldName('defaultBillingAddressId') + ->withFieldSourcePath('default_billing_address_id') + ->withSourceData($originalData) + ->build(FieldReassignedRunLog::class) + ); } } @@ -731,30 +678,20 @@ protected function getSalutation(string $salutation): ?string ); if ($mapping === null) { - $this->loggingService->addLogEntry(new UnknownEntityLog( - $this->runId, - DefaultEntities::SALUTATION, - $salutation, - DefaultEntities::CUSTOMER, - $this->oldCustomerId - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(CustomerDefinition::ENTITY_NAME) + ->withFieldName('salutationId') + ->withFieldSourcePath('salutation') + ->withSourceData(['salutation' => $salutation]) + ->build(UnknownEntityLog::class) + ); return null; } $this->mappingIds[] = $mapping['id']; - return $mapping['entityUuid']; - } - - protected function checkEmailValidity(string $email): bool - { - $constraint = new Email(); - $errors = $this->validator->validate( - $email, - $constraint - ); - - return \count($errors) === 0; + return $mapping['entityId']; } /** diff --git a/src/Profile/Shopware/Converter/CustomerGroupConverter.php b/src/Profile/Shopware/Converter/CustomerGroupConverter.php index b77dcc163..4d0bd165c 100644 --- a/src/Profile/Shopware/Converter/CustomerGroupConverter.php +++ b/src/Profile/Shopware/Converter/CustomerGroupConverter.php @@ -44,12 +44,8 @@ public function convert(array $data, Context $context, MigrationContextInterface unset($data['_locale']); $connection = $migrationContext->getConnection(); - $this->connectionId = ''; - $this->connectionName = ''; - if ($connection !== null) { - $this->connectionId = $connection->getId(); - $this->connectionName = $connection->getName(); - } + $this->connectionId = $connection->getId(); + $this->connectionName = $connection->getName(); $this->mainMapping = $this->mappingService->getOrCreateMapping( $this->connectionId, @@ -60,7 +56,7 @@ public function convert(array $data, Context $context, MigrationContextInterface ); $converted = []; - $converted['id'] = $this->mainMapping['entityUuid']; + $converted['id'] = $this->mainMapping['entityId']; if (isset($data['attributes'])) { $converted['customFields'] = $this->getAttributes($data['attributes'], DefaultEntities::CUSTOMER_GROUP, $this->connectionName, ['id', 'customerGroupID'], $this->context); @@ -109,7 +105,7 @@ public function getCustomerGroupTranslation(array &$customerGroup, array $data): $data['id'] . ':' . $this->locale, $this->context ); - $localeTranslation['id'] = $mapping['entityUuid']; + $localeTranslation['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $languageUuid = $this->languageLookup->get($this->locale, $this->context); diff --git a/src/Profile/Shopware/Converter/CustomerWishlistConverter.php b/src/Profile/Shopware/Converter/CustomerWishlistConverter.php index 516cb3dba..7bcbe3261 100644 --- a/src/Profile/Shopware/Converter/CustomerWishlistConverter.php +++ b/src/Profile/Shopware/Converter/CustomerWishlistConverter.php @@ -27,10 +27,7 @@ public function convert(array $data, Context $context, MigrationContextInterface $this->migrationContext = $migrationContext; $connection = $migrationContext->getConnection(); - $this->connectionId = ''; - if ($connection !== null) { - $this->connectionId = $connection->getId(); - } + $this->connectionId = $connection->getId(); $this->mainMapping = $this->mappingService->getOrCreateMapping( $this->connectionId, @@ -40,31 +37,31 @@ public function convert(array $data, Context $context, MigrationContextInterface $this->checksum ); + $converted = []; + $customerMapping = $this->mappingService->getMapping($this->connectionId, DefaultEntities::CUSTOMER, $data['userID'], $context); - if ($customerMapping === null) { - return new ConvertStruct(null, $data); + if ($customerMapping !== null) { + $this->mappingIds[] = $customerMapping['id']; + $converted['customerId'] = $customerMapping['entityId']; } + $productId = null; $productMapping = $this->mappingService->getMapping($this->connectionId, DefaultEntities::PRODUCT, $data['ordernumber'], $context); - if ($productMapping === null) { - return new ConvertStruct(null, $data); + if ($productMapping !== null) { + $this->mappingIds[] = $productMapping['id']; + $productId = $productMapping['entityId']; } $shopMapping = $this->mappingService->getMapping($this->connectionId, DefaultEntities::SALES_CHANNEL, $data['subshopID'], $context); - if ($shopMapping === null) { - return new ConvertStruct(null, $data); + if ($shopMapping !== null) { + $converted['salesChannelId'] = $shopMapping['entityId']; } - $this->mappingIds[] = $customerMapping['id']; - $this->mappingIds[] = $productMapping['id']; + $converted['id'] = $this->mainMapping['entityId']; - $converted = []; - $converted['id'] = $this->mainMapping['entityUuid']; - $converted['customerId'] = $customerMapping['entityUuid']; - $converted['salesChannelId'] = $shopMapping['entityUuid']; $converted['products'][] = [ - 'id' => $this->mappingService->getOrCreateMapping($this->connectionId, DefaultEntities::CUSTOMER_WISHLIST_PRODUCT, $data['userID'] . '_' . $data['ordernumber'], $context)['entityUuid'], - 'productId' => $productMapping['entityUuid'], + 'id' => $this->mappingService->getOrCreateMapping($this->connectionId, DefaultEntities::CUSTOMER_WISHLIST_PRODUCT, $data['userID'] . '_' . $data['ordernumber'], $context)['entityId'], + 'productId' => $productId, ]; $this->updateMainMapping($migrationContext, $context); diff --git a/src/Profile/Shopware/Converter/LanguageConverter.php b/src/Profile/Shopware/Converter/LanguageConverter.php index c35293ab4..d0732d893 100644 --- a/src/Profile/Shopware/Converter/LanguageConverter.php +++ b/src/Profile/Shopware/Converter/LanguageConverter.php @@ -11,7 +11,6 @@ use Shopware\Core\Framework\Log\Package; use SwagMigrationAssistant\Migration\Converter\ConvertStruct; use SwagMigrationAssistant\Migration\DataSelection\DefaultEntities; -use SwagMigrationAssistant\Migration\Logging\Log\EntityAlreadyExistsRunLog; use SwagMigrationAssistant\Migration\Logging\LoggingServiceInterface; use SwagMigrationAssistant\Migration\Mapping\Lookup\LanguageLookup; use SwagMigrationAssistant\Migration\Mapping\Lookup\LocaleLookup; @@ -28,8 +27,8 @@ abstract class LanguageConverter extends ShopwareConverter public function __construct( MappingServiceInterface $mappingService, LoggingServiceInterface $loggingService, - protected readonly LanguageLookup $languageLookup, protected readonly LocaleLookup $localeLookup, + protected readonly LanguageLookup $languageLookup, ) { parent::__construct($mappingService, $loggingService); } @@ -39,26 +38,17 @@ public function getSourceIdentifier(array $data): string return $data['locale']; } - public function convert(array $data, Context $context, MigrationContextInterface $migrationContext): ConvertStruct + public function convert(array $data, Context $context, MigrationContextInterface $migrationContext): ?ConvertStruct { $this->generateChecksum($data); $this->context = $context; $connection = $migrationContext->getConnection(); - $this->connectionId = ''; - if ($connection !== null) { - $this->connectionId = $connection->getId(); - } + $this->connectionId = $connection->getId(); $languageUuid = $this->languageLookup->get($data['locale'], $context); if ($languageUuid !== null) { - $this->loggingService->addLogEntry(new EntityAlreadyExistsRunLog( - $migrationContext->getRunUuid(), - DefaultEntities::LANGUAGE, - $data['id'] - )); - - return new ConvertStruct(null, $data); + return null; } $converted = []; @@ -69,7 +59,7 @@ public function convert(array $data, Context $context, MigrationContextInterface $context, $this->checksum ); - $converted['id'] = $this->mainMapping['entityUuid']; + $converted['id'] = $this->mainMapping['entityId']; $this->convertValue($converted, 'name', $data, 'language'); diff --git a/src/Profile/Shopware/Converter/MainVariantRelationConverter.php b/src/Profile/Shopware/Converter/MainVariantRelationConverter.php index f6bfcfe79..17748310b 100644 --- a/src/Profile/Shopware/Converter/MainVariantRelationConverter.php +++ b/src/Profile/Shopware/Converter/MainVariantRelationConverter.php @@ -11,7 +11,8 @@ use Shopware\Core\Framework\Log\Package; use SwagMigrationAssistant\Migration\Converter\ConvertStruct; use SwagMigrationAssistant\Migration\DataSelection\DefaultEntities; -use SwagMigrationAssistant\Migration\Logging\Log\AssociationRequiredMissingLog; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogBuilder; +use SwagMigrationAssistant\Migration\Logging\Log\MainVariantRelationNotConverted; use SwagMigrationAssistant\Migration\MigrationContextInterface; #[Package('fundamentals@after-sales')] @@ -21,25 +22,28 @@ abstract class MainVariantRelationConverter extends ShopwareConverter protected string $connectionId = ''; - private string $runUuid; - public function getSourceIdentifier(array $data): string { return $data['id']; } - public function convert(array $data, Context $context, MigrationContextInterface $migrationContext): ConvertStruct + public function convert(array $data, Context $context, MigrationContextInterface $migrationContext): ?ConvertStruct { $this->generateChecksum($data); $this->context = $context; - $this->runUuid = $migrationContext->getRunUuid(); $connection = $migrationContext->getConnection(); - if ($connection !== null) { - $this->connectionId = $connection->getId(); - } + $this->connectionId = $connection->getId(); if (!isset($data['id'], $data['ordernumber'])) { - return new ConvertStruct(null, $data); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withSourceData($data) + ->withExceptionMessage('MainVariantRelation requires ID and order number, to be converted successful') + ->withExceptionTrace(\debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS, 2)) + ->build(MainVariantRelationNotConverted::class) + ); + + return null; } $this->mainMapping = $this->mappingService->getOrCreateMapping( @@ -64,28 +68,21 @@ public function convert(array $data, Context $context, MigrationContextInterface $context ); - if ($mainProductMapping === null) { - $this->addAssociationRequiredLog(DefaultEntities::PRODUCT_CONTAINER, $data['id']); + $converted = []; - return new ConvertStruct(null, $data); + if ($mainProductMapping !== null) { + $this->mappingIds[] = $mainProductMapping['id']; + $converted['id'] = $mainProductMapping['entityId']; } - if ($variantProductMapping === null) { - $this->addAssociationRequiredLog(DefaultEntities::PRODUCT, $data['ordernumber']); - - return new ConvertStruct(null, $data); + if ($variantProductMapping !== null) { + $this->mappingIds[] = $variantProductMapping['id']; + $converted['variantListingConfig'] = [ + 'displayParent' => true, + 'mainVariantId' => $variantProductMapping['entityId'], + ]; } - $this->mappingIds[] = $mainProductMapping['id']; - $this->mappingIds[] = $variantProductMapping['id']; - - $converted = []; - $converted['id'] = $mainProductMapping['entityUuid']; - - $converted['variantListingConfig'] = [ - 'displayParent' => true, - 'mainVariantId' => $variantProductMapping['entityUuid'], - ]; unset($data['id'], $data['ordernumber']); $returnData = $data; @@ -97,16 +94,4 @@ public function convert(array $data, Context $context, MigrationContextInterface return new ConvertStruct($converted, $returnData, $this->mainMapping['id'] ?? null); } - - private function addAssociationRequiredLog(string $requiredEntity, string $id): void - { - $this->loggingService->addLogEntry( - new AssociationRequiredMissingLog( - $this->runUuid, - $requiredEntity, - $id, - DefaultEntities::MAIN_VARIANT_RELATION - ) - ); - } } diff --git a/src/Profile/Shopware/Converter/MediaConverter.php b/src/Profile/Shopware/Converter/MediaConverter.php index c7285189e..8ad55bbb6 100644 --- a/src/Profile/Shopware/Converter/MediaConverter.php +++ b/src/Profile/Shopware/Converter/MediaConverter.php @@ -57,10 +57,7 @@ public function convert( unset($data['_locale']); $connection = $migrationContext->getConnection(); - $this->connectionId = ''; - if ($connection !== null) { - $this->connectionId = $connection->getId(); - } + $this->connectionId = $connection->getId(); $converted = []; $this->mainMapping = $this->mappingService->getOrCreateMapping( @@ -70,7 +67,7 @@ public function convert( $context, $this->checksum ); - $converted['id'] = $this->mainMapping['entityUuid']; + $converted['id'] = $this->mainMapping['entityId']; if (empty($data['name'])) { $data['name'] = $converted['id']; @@ -100,7 +97,7 @@ public function convert( ); if ($albumMapping !== null) { - $converted['mediaFolderId'] = $albumMapping['entityUuid']; + $converted['mediaFolderId'] = $albumMapping['entityId']; $this->mappingIds[] = $albumMapping['id']; } @@ -151,7 +148,7 @@ protected function getMediaTranslation(array &$media, array $data): void $data['id'] . ':' . $this->locale, $this->context ); - $localeTranslation['id'] = $mapping['entityUuid']; + $localeTranslation['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $languageUuid = $this->languageLookup->get($this->locale, $this->context); diff --git a/src/Profile/Shopware/Converter/MediaFolderConverter.php b/src/Profile/Shopware/Converter/MediaFolderConverter.php index 30b4bdb25..ab8cde69a 100644 --- a/src/Profile/Shopware/Converter/MediaFolderConverter.php +++ b/src/Profile/Shopware/Converter/MediaFolderConverter.php @@ -50,10 +50,7 @@ public function convert(array $data, Context $context, MigrationContextInterface unset($data['_locale']); $connection = $migrationContext->getConnection(); - $this->connectionId = ''; - if ($connection !== null) { - $this->connectionId = $connection->getId(); - } + $this->connectionId = $connection->getId(); $converted = []; $this->mainMapping = $this->mappingService->getOrCreateMapping( @@ -63,7 +60,7 @@ public function convert(array $data, Context $context, MigrationContextInterface $this->context, $this->checksum ); - $converted['id'] = $this->mainMapping['entityUuid']; + $converted['id'] = $this->mainMapping['entityId']; unset($data['id']); $defaultFolderId = $this->getDefaultFolderId(); @@ -80,7 +77,7 @@ public function convert(array $data, Context $context, MigrationContextInterface ); if ($parentMapping !== null) { - $converted['parentId'] = $parentMapping['entityUuid']; + $converted['parentId'] = $parentMapping['entityId']; $this->mappingIds[] = $parentMapping['id']; } unset($parentMapping); @@ -104,10 +101,10 @@ public function convert(array $data, Context $context, MigrationContextInterface $this->mappingIds[] = $configurationMapping['id']; $converted['parent'] = [ - 'id' => $parentMapping['entityUuid'], + 'id' => $parentMapping['entityId'], 'name' => 'Migration media folder', 'configuration' => [ - 'id' => $configurationMapping['entityUuid'], + 'id' => $configurationMapping['entityId'], ], ]; } @@ -151,7 +148,7 @@ protected function getConfiguration(array &$setting, MigrationContextInterface $ $setting['id'], $this->context ); - $configuration['id'] = $mapping['entityUuid']; + $configuration['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $this->convertValue($configuration, 'createThumbnails', $setting, 'create_thumbnails', self::TYPE_BOOLEAN); @@ -176,7 +173,7 @@ protected function getConfiguration(array &$setting, MigrationContextInterface $ $thumbnailSize['width'] . '-' . $thumbnailSize['height'], $this->context ); - $uuid = $mapping['entityUuid']; + $uuid = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; } diff --git a/src/Profile/Shopware/Converter/NewsletterRecipientConverter.php b/src/Profile/Shopware/Converter/NewsletterRecipientConverter.php index adc1fe172..6b97460bb 100644 --- a/src/Profile/Shopware/Converter/NewsletterRecipientConverter.php +++ b/src/Profile/Shopware/Converter/NewsletterRecipientConverter.php @@ -7,11 +7,13 @@ namespace SwagMigrationAssistant\Profile\Shopware\Converter; +use Shopware\Core\Content\Newsletter\Aggregate\NewsletterRecipient\NewsletterRecipientDefinition; use Shopware\Core\Framework\Context; use Shopware\Core\Framework\Log\Package; use Shopware\Core\Framework\Uuid\Uuid; use SwagMigrationAssistant\Migration\Converter\ConvertStruct; use SwagMigrationAssistant\Migration\DataSelection\DefaultEntities; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogBuilder; use SwagMigrationAssistant\Migration\Logging\Log\EmptyNecessaryFieldRunLog; use SwagMigrationAssistant\Migration\Logging\Log\UnknownEntityLog; use SwagMigrationAssistant\Migration\Logging\LoggingServiceInterface; @@ -34,14 +36,6 @@ abstract class NewsletterRecipientConverter extends ShopwareConverter protected string $runId; - /** - * @var list - */ - protected array $requiredDataFieldKeys = [ - '_locale', - 'shopId', - ]; - public function __construct( MappingServiceInterface $mappingService, LoggingServiceInterface $loggingService, @@ -55,31 +49,16 @@ public function convert( Context $context, MigrationContextInterface $migrationContext, ): ConvertStruct { - $this->runId = $migrationContext->getRunUuid(); - $fields = $this->checkForEmptyRequiredDataFields($data, $this->requiredDataFieldKeys); + $connection = $migrationContext->getConnection(); + $this->connectionId = $connection->getId(); - if (!empty($fields)) { - $this->loggingService->addLogEntry(new EmptyNecessaryFieldRunLog( - $this->runId, - DefaultEntities::NEWSLETTER_RECIPIENT, - $data['id'], - \implode(',', $fields) - )); + $this->runId = $migrationContext->getRunUuid(); - return new ConvertStruct(null, $data); - } - $oldData = $data; $this->generateChecksum($data); $this->context = $context; $this->locale = $data['_locale']; unset($data['_locale']); - $connection = $migrationContext->getConnection(); - $this->connectionId = ''; - if ($connection !== null) { - $this->connectionId = $connection->getId(); - } - $converted = []; $this->oldNewsletterRecipientId = $data['id']; $this->mainMapping = $this->mappingService->getOrCreateMapping( @@ -89,7 +68,7 @@ public function convert( $context, $this->checksum ); - $converted['id'] = $this->mainMapping['entityUuid']; + $converted['id'] = $this->mainMapping['entityId']; $this->convertValue($converted, 'email', $data, 'email'); $this->convertValue($converted, 'createdAt', $data, 'added', 'datetime'); @@ -104,7 +83,7 @@ public function convert( $this->convertValue($converted, 'city', $address, 'city'); if (isset($address['salutation'])) { - $salutationUuid = $this->getSalutation($address['salutation']); + $salutationUuid = $this->getSalutation($address['salutation'], $migrationContext); if ($salutationUuid !== null) { $converted['salutationId'] = $salutationUuid; } @@ -116,24 +95,22 @@ public function convert( if (isset($converted['confirmedAt'])) { $status = 'optIn'; } else { - $status = $this->getStatus(); + $status = $this->getStatus($migrationContext); } - if ($status === null) { - return new ConvertStruct(null, $oldData); + if ($status !== null) { + $converted['status'] = $status; } - $converted['status'] = $status; $converted['languageId'] = $this->languageLookup->get($this->locale, $context); $salesChannelUuid = $this->getSalesChannel($data); - if ($salesChannelUuid === null) { - return new ConvertStruct(null, $oldData); + if ($salesChannelUuid !== null) { + $converted['salesChannelId'] = $salesChannelUuid; } - unset($data['shopId']); - $converted['salesChannelId'] = $salesChannelUuid; unset( + $data['shopId'], $data['id'], $data['groupID'], $data['lastmailing'], @@ -150,7 +127,7 @@ public function convert( return new ConvertStruct($converted, $returnData, $this->mainMapping['id'] ?? null); } - protected function getSalutation(string $salutation): ?string + protected function getSalutation(string $salutation, MigrationContextInterface $migrationContext): ?string { $salutationMapping = $this->mappingService->getMapping( $this->connectionId, @@ -160,19 +137,19 @@ protected function getSalutation(string $salutation): ?string ); if ($salutationMapping === null) { - $this->loggingService->addLogEntry(new UnknownEntityLog( - $this->runId, - 'salutation', - $salutation, - DefaultEntities::NEWSLETTER_RECIPIENT, - $this->oldNewsletterRecipientId - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withEntityName(NewsletterRecipientDefinition::ENTITY_NAME) + ->withFieldName('salutationId') + ->withSourceData(['salutation' => $salutation]) + ->build(UnknownEntityLog::class) + ); return null; } $this->mappingIds[] = $salutationMapping['id']; - return $salutationMapping['entityUuid']; + return $salutationMapping['entityId']; } /** @@ -190,21 +167,23 @@ protected function getSalesChannel(array $data): ?string } if (!isset($salesChannelMapping)) { - $this->loggingService->addLogEntry(new EmptyNecessaryFieldRunLog( - $this->runId, - DefaultEntities::NEWSLETTER_RECIPIENT, - $this->oldNewsletterRecipientId, - 'salesChannel' - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(NewsletterRecipientDefinition::ENTITY_NAME) + ->withFieldName('salesChannelId') + ->withFieldSourcePath('shopId') + ->withSourceData($data) + ->build(EmptyNecessaryFieldRunLog::class) + ); return null; } $this->mappingIds[] = $salesChannelMapping['id']; - return $salesChannelMapping['entityUuid']; + return $salesChannelMapping['entityId']; } - protected function getStatus(): ?string + protected function getStatus(MigrationContextInterface $migrationContext): ?string { $status = $this->mappingService->getValue( $this->connectionId, @@ -214,12 +193,13 @@ protected function getStatus(): ?string ); if ($status === null) { - $this->loggingService->addLogEntry(new EmptyNecessaryFieldRunLog( - $this->runId, - DefaultEntities::NEWSLETTER_RECIPIENT, - $this->oldNewsletterRecipientId, - 'status' - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withEntityName(NewsletterRecipientDefinition::ENTITY_NAME) + ->withFieldName('status') + ->withSourceData(['status' => NewsletterRecipientStatusReader::SOURCE_ID]) + ->build(EmptyNecessaryFieldRunLog::class) + ); } return $status; diff --git a/src/Profile/Shopware/Converter/NumberRangeConverter.php b/src/Profile/Shopware/Converter/NumberRangeConverter.php index 6809c65d0..8ca84d57b 100644 --- a/src/Profile/Shopware/Converter/NumberRangeConverter.php +++ b/src/Profile/Shopware/Converter/NumberRangeConverter.php @@ -17,13 +17,11 @@ use Shopware\Core\System\NumberRange\NumberRangeEntity; use SwagMigrationAssistant\Migration\Converter\ConvertStruct; use SwagMigrationAssistant\Migration\DataSelection\DefaultEntities; -use SwagMigrationAssistant\Migration\Logging\Log\EmptyNecessaryFieldRunLog; use SwagMigrationAssistant\Migration\Logging\LoggingServiceInterface; use SwagMigrationAssistant\Migration\Mapping\Lookup\LanguageLookup; use SwagMigrationAssistant\Migration\Mapping\Lookup\NumberRangeLookup; use SwagMigrationAssistant\Migration\Mapping\MappingServiceInterface; use SwagMigrationAssistant\Migration\MigrationContextInterface; -use SwagMigrationAssistant\Profile\Shopware\Logging\Log\UnsupportedNumberRangeTypeLog; #[Package('fundamentals@after-sales')] abstract class NumberRangeConverter extends ShopwareConverter @@ -67,38 +65,12 @@ public function convert(array $data, Context $context, MigrationContextInterface $this->numberRangeTypes = $this->numberRangeTypeRepo->search(new Criteria(), $context)->getEntities(); } - if (!\array_key_exists($data['name'], self::TYPE_MAPPING)) { - $this->loggingService->addLogEntry( - new UnsupportedNumberRangeTypeLog( - $migrationContext->getRunUuid(), - DefaultEntities::NUMBER_RANGE, - $data['id'], - $data['name'] - ) - ); - - return new ConvertStruct(null, $data); - } - $connection = $migrationContext->getConnection(); - if ($connection === null) { - return new ConvertStruct(null, $data); - } $this->connectionId = $connection->getId(); - $converted = []; $converted['id'] = $this->getUuid($data, $migrationContext, $context); - $converted['typeId'] = $this->getProductNumberRangeTypeUuid($data['name']); - - if (empty($converted['typeId'])) { - $this->loggingService->addLogEntry(new EmptyNecessaryFieldRunLog( - $migrationContext->getRunUuid(), - DefaultEntities::NUMBER_RANGE, - $data['id'], - 'typeId' - )); - - return new ConvertStruct(null, $data); + if (\array_key_exists($data['name'], self::TYPE_MAPPING)) { + $converted['typeId'] = $this->getProductNumberRangeTypeUuid($data['name']); } $converted['global'] = $this->getGlobal($data['name']); @@ -152,7 +124,7 @@ protected function getUuid(array $data, MigrationContextInterface $migrationCont if ($mapping !== null) { $this->mainMapping = $mapping; - return (string) $mapping['entityUuid']; + return (string) $mapping['entityId']; } // use global number range uuid for products if available @@ -168,7 +140,7 @@ protected function getUuid(array $data, MigrationContextInterface $migrationCont 'connectionId' => $this->connectionId, 'entity' => DefaultEntities::NUMBER_RANGE, 'oldIdentifier' => $data['id'], - 'entityUuid' => $productNumberRageUuid, + 'entityId' => $productNumberRageUuid, 'checksum' => null, 'entityValue' => null, 'additionalData' => null, @@ -186,7 +158,7 @@ protected function getUuid(array $data, MigrationContextInterface $migrationCont $this->checksum ); - return (string) $this->mainMapping['entityUuid']; + return (string) $this->mainMapping['entityId']; } protected function getProductNumberRangeTypeUuid(string $type): ?string @@ -239,7 +211,7 @@ protected function setNumberRangeTranslation( $data['id'] . ':' . $data['_locale'], $context ); - $localeTranslation['id'] = $mapping['entityUuid']; + $localeTranslation['id'] = $mapping['entityId']; $languageUuid = $this->languageLookup->get($data['_locale'], $context); if ($languageUuid !== null) { @@ -264,10 +236,10 @@ protected function setNumberRangeSalesChannels(array &$converted, Context $conte $context ); $numberRangeSalesChannel = []; - $numberRangeSalesChannel['id'] = $mapping['entityUuid']; + $numberRangeSalesChannel['id'] = $mapping['entityId']; $numberRangeSalesChannel['numberRangeId'] = $converted['id']; $numberRangeSalesChannel['salesChannelId'] = $saleChannelId; - $numberRangeSalesChannel['numberRangeTypeId'] = $converted['typeId']; + $numberRangeSalesChannel['numberRangeTypeId'] = $converted['typeId'] ?? null; $numberRangeSalesChannels[] = $numberRangeSalesChannel; $this->mappingIds[] = $mapping['id']; } diff --git a/src/Profile/Shopware/Converter/OrderConverter.php b/src/Profile/Shopware/Converter/OrderConverter.php index 07c528830..759752370 100644 --- a/src/Profile/Shopware/Converter/OrderConverter.php +++ b/src/Profile/Shopware/Converter/OrderConverter.php @@ -17,18 +17,23 @@ use Shopware\Core\Checkout\Cart\Tax\Struct\TaxRule; use Shopware\Core\Checkout\Cart\Tax\Struct\TaxRuleCollection; use Shopware\Core\Checkout\Cart\Tax\TaxCalculator; +use Shopware\Core\Checkout\Order\Aggregate\OrderAddress\OrderAddressDefinition; +use Shopware\Core\Checkout\Order\Aggregate\OrderDelivery\OrderDeliveryDefinition; +use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemDefinition; +use Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionDefinition; use Shopware\Core\Defaults; use Shopware\Core\Framework\Context; use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository; use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria; use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter; use Shopware\Core\Framework\Log\Package; +use Shopware\Core\Framework\Util\Hasher; use Shopware\Core\System\SalesChannel\SalesChannelCollection; use SwagMigrationAssistant\Exception\AssociationEntityRequiredMissingException; use SwagMigrationAssistant\Exception\MigrationException; use SwagMigrationAssistant\Migration\Converter\ConvertStruct; use SwagMigrationAssistant\Migration\DataSelection\DefaultEntities; -use SwagMigrationAssistant\Migration\Logging\Log\EmptyNecessaryFieldRunLog; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogBuilder; use SwagMigrationAssistant\Migration\Logging\Log\UnknownEntityLog; use SwagMigrationAssistant\Migration\Logging\LoggingServiceInterface; use SwagMigrationAssistant\Migration\Mapping\Lookup\CountryLookup; @@ -64,29 +69,6 @@ abstract class OrderConverter extends ShopwareConverter protected string $runId; - /** - * @var list - */ - protected array $requiredDataFieldKeys = [ - 'customer', - 'currency', - 'currencyFactor', - 'payment', - 'status', - ]; - - /** - * @var list - */ - protected array $requiredAddressDataFieldKeys = [ - 'firstname', - 'lastname', - 'zipcode', - 'city', - 'street', - 'salutation', - ]; - protected int $paymentStatusId; /** @@ -118,37 +100,14 @@ public function convert( $this->runId = $migrationContext->getRunUuid(); $this->migrationContext = $migrationContext; - $fields = $this->checkForEmptyRequiredDataFields($data, $this->requiredDataFieldKeys); - if (empty($data['billingaddress']['id'])) { - $fields[] = 'billingaddress'; - } - if (isset($data['payment']) && empty($data['payment']['name'])) { - $fields[] = 'paymentMethod'; - } - - if (!empty($fields)) { - $this->loggingService->addLogEntry(new EmptyNecessaryFieldRunLog( - $this->runId, - DefaultEntities::ORDER, - $this->oldId, - \implode(',', $fields) - )); - - return new ConvertStruct(null, $data); - } + $connection = $migrationContext->getConnection(); + $this->connectionId = $connection->getId(); + $this->connectionName = $connection->getName(); $this->mainLocale = $data['_locale']; unset($data['_locale']); $this->context = $context; - $connection = $migrationContext->getConnection(); - $this->connectionName = ''; - $this->connectionId = ''; - if ($connection !== null) { - $this->connectionId = $connection->getId(); - $this->connectionName = $connection->getName(); - } - $converted = []; $this->mainMapping = $this->mappingService->getOrCreateMapping( $this->connectionId, @@ -157,7 +116,7 @@ public function convert( $this->context, $this->checksum ); - $converted['id'] = (string) $this->mainMapping['entityUuid']; + $converted['id'] = (string) $this->mainMapping['entityId']; unset($data['id']); $this->uuid = $converted['id']; @@ -190,24 +149,28 @@ public function convert( ); $converted['orderCustomer'] = [ - 'id' => $orderCustomerMapping['entityUuid'], - 'customerId' => $customerMapping['entityUuid'], + 'id' => $orderCustomerMapping['entityId'], + 'customerId' => $customerMapping['entityId'], ]; $this->mappingIds[] = $customerMapping['id']; $this->mappingIds[] = $orderCustomerMapping['id']; unset($customerMapping); - $salutationUuid = $this->getSalutation($data['customer']['salutation']); - if ($salutationUuid === null) { - return new ConvertStruct(null, $data); + $salutationUuid = null; + if (isset($data['customer']['salutation'])) { + $salutationUuid = $this->getSalutation($data['customer']['salutation']); + } + if ($salutationUuid !== null) { + $converted['orderCustomer']['salutationId'] = $salutationUuid; } - $converted['orderCustomer']['salutationId'] = $salutationUuid; - $this->convertValue($converted['orderCustomer'], 'email', $data['customer'], 'email'); - $this->convertValue($converted['orderCustomer'], 'firstName', $data['customer'], 'firstname'); - $this->convertValue($converted['orderCustomer'], 'lastName', $data['customer'], 'lastname'); - $this->convertValue($converted['orderCustomer'], 'customerNumber', $data['customer'], 'customernumber'); - unset($data['userID'], $data['customer']); + if (isset($data['customer'])) { + $this->convertValue($converted['orderCustomer'], 'email', $data['customer'], 'email'); + $this->convertValue($converted['orderCustomer'], 'firstName', $data['customer'], 'firstname'); + $this->convertValue($converted['orderCustomer'], 'lastName', $data['customer'], 'lastname'); + $this->convertValue($converted['orderCustomer'], 'customerNumber', $data['customer'], 'customernumber'); + unset($data['userID'], $data['customer']); + } $this->convertValue($converted, 'currencyFactor', $data, 'currencyFactor', self::TYPE_FLOAT); @@ -215,19 +178,10 @@ public function convert( if (isset($data['currency'])) { $currencyUuid = $this->currencyLookup->get($data['currency'], $context); } - if ($currencyUuid === null) { - $this->loggingService->addLogEntry(new EmptyNecessaryFieldRunLog( - $this->runId, - DefaultEntities::ORDER, - $this->oldId, - 'currency' - )); - - return new ConvertStruct(null, $data); + if ($currencyUuid !== null) { + $converted['currencyId'] = $currencyUuid; } - $converted['currencyId'] = $currencyUuid; - $converted['itemRounding'] = [ 'decimals' => $context->getRounding()->getDecimals(), 'interval' => 0.01, @@ -237,26 +191,20 @@ public function convert( $this->convertValue($converted, 'orderDateTime', $data, 'ordertime', self::TYPE_DATETIME); - $stateMapping = $this->mappingService->getMapping( - $this->connectionId, - OrderStateReader::getMappingName(), - (string) $data['status'], - $this->context - ); - - if ($stateMapping === null) { - $this->loggingService->addLogEntry(new UnknownEntityLog( - $this->runId, - 'order_state', + $stateMapping = null; + if (isset($data['status'])) { + $stateMapping = $this->mappingService->getMapping( + $this->connectionId, + OrderStateReader::getMappingName(), (string) $data['status'], - DefaultEntities::ORDER, - $this->oldId - )); + $this->context + ); + } - return new ConvertStruct(null, $data); + if ($stateMapping !== null) { + $converted['stateId'] = $stateMapping['entityId']; + $this->mappingIds[] = $stateMapping['id']; } - $converted['stateId'] = $stateMapping['entityUuid']; - $this->mappingIds[] = $stateMapping['id']; $shippingGross = (float) $data['invoice_shipping']; $shippingNet = (float) $data['invoice_shipping_net']; @@ -321,22 +269,18 @@ public function convert( $this->applyTransactions($data, $converted); unset($data['cleared'], $data['paymentstatus']); - $billingAddress = $this->getAddress($data['billingaddress']); - if (empty($billingAddress)) { - $this->loggingService->addLogEntry(new EmptyNecessaryFieldRunLog( - $this->runId, - DefaultEntities::ORDER, - $this->oldId, - 'billingaddress' - )); + $billingAddress = null; + if (isset($data['billingaddress']) && \is_array($data['billingaddress'])) { + $billingAddress = $this->getAddress($data['billingaddress']); + } - return new ConvertStruct(null, $data); + if (!empty($billingAddress)) { + $converted['billingAddressId'] = $billingAddress['id']; + $converted['addresses'][] = $billingAddress; } if (isset($data['billingaddress']['ustid']) && $data['billingaddress']['ustid'] !== '') { $converted['orderCustomer']['vatIds'][] = $data['billingaddress']['ustid']; } - $converted['billingAddressId'] = $billingAddress['id']; - $converted['addresses'][] = $billingAddress; unset($data['billingaddress']); if (isset($data['subshopID'])) { @@ -348,7 +292,7 @@ public function convert( ); if ($mapping !== null) { - $converted['salesChannelId'] = $mapping['entityUuid']; + $converted['salesChannelId'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; unset($data['subshopID']); } @@ -374,7 +318,7 @@ public function convert( } unset($data['locale']); - $converted['deepLinkCode'] = \md5($converted['id']); + $converted['deepLinkCode'] = Hasher::hash($converted['id']); // Legacy data which don't need a mapping or there is no equivalent field unset( @@ -429,17 +373,19 @@ protected function applyTransactions(array $data, array &$converted): void ); if ($mapping === null) { - $this->loggingService->addLogEntry(new UnknownEntityLog( - $this->runId, - 'transaction_state', - $data['cleared'], - DefaultEntities::ORDER_TRANSACTION, - $this->oldId - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(OrderTransactionDefinition::ENTITY_NAME) + ->withFieldName('stateId') + ->withFieldSourcePath('cleared') + ->withSourceData($data) + ->withConvertedData($converted) + ->build(UnknownEntityLog::class) + ); return; } - $stateId = $mapping['entityUuid']; + $stateId = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $mapping = $this->mappingService->getOrCreateMapping( @@ -454,7 +400,7 @@ protected function applyTransactions(array $data, array &$converted): void if ($paymentMethodUuid === null) { return; } - $id = $mapping['entityUuid']; + $id = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $transactions = [ @@ -479,28 +425,32 @@ protected function applyTransactions(array $data, array &$converted): void */ protected function getPaymentMethod(array $originalData): ?string { - $paymentMethodMapping = $this->mappingService->getMapping( - $this->connectionId, - PaymentMethodReader::getMappingName(), - $originalData['payment']['id'], - $this->context - ); + $paymentMethodMapping = null; + if (isset($originalData['payment']['id'])) { + $paymentMethodMapping = $this->mappingService->getMapping( + $this->connectionId, + PaymentMethodReader::getMappingName(), + $originalData['payment']['id'], + $this->context + ); + } if ($paymentMethodMapping === null) { - $this->loggingService->addLogEntry(new UnknownEntityLog( - $this->runId, - 'payment_method', - $originalData['payment']['id'], - DefaultEntities::ORDER_TRANSACTION, - $this->oldId - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(OrderTransactionDefinition::ENTITY_NAME) + ->withFieldName('paymentMethodId') + ->withFieldSourcePath('payment.id') + ->withSourceData($originalData) + ->build(UnknownEntityLog::class) + ); return null; } $this->mappingIds[] = $paymentMethodMapping['id']; - return $paymentMethodMapping['entityUuid']; + return $paymentMethodMapping['entityId']; } /** @@ -510,18 +460,6 @@ protected function getPaymentMethod(array $originalData): ?string */ protected function getAddress(array $originalData, string $type = self::BILLING_ADDRESS): array { - $fields = $this->checkForEmptyRequiredDataFields($originalData, $this->requiredAddressDataFieldKeys); - if (!empty($fields)) { - $this->loggingService->addLogEntry(new EmptyNecessaryFieldRunLog( - $this->runId, - DefaultEntities::ORDER_ADDRESS, - $originalData['id'], - \implode(',', $fields) - )); - - return []; - } - $entityName = DefaultEntities::ORDER_ADDRESS; if ($type !== self::BILLING_ADDRESS) { $entityName = DefaultEntities::ORDER_ADDRESS . '_' . $type; @@ -534,7 +472,7 @@ protected function getAddress(array $originalData, string $type = self::BILLING_ $originalData['id'], $this->context ); - $address['id'] = $mapping['entityUuid']; + $address['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $address['country'] = $this->getCountry($originalData['country']); @@ -587,7 +525,7 @@ protected function getCountry(array $oldCountryData): array $oldCountryData['id'], $this->context ); - $country['id'] = $mapping['entityUuid']; + $country['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; } @@ -633,7 +571,7 @@ protected function applyCountryTranslation(array &$country, array $data): void $data['id'] . ':' . $this->mainLocale, $this->context ); - $localeTranslation['id'] = $mapping['entityUuid']; + $localeTranslation['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $languageUuid = $this->languageLookup->get($this->mainLocale, $this->context); @@ -658,13 +596,12 @@ protected function getCountryState(array $oldAddressData, string $newCountryId): if (!isset($oldAddressData['stateID'], $oldAddressData['country']['countryiso'], $oldAddressData['state']['shortcode'])) { $this->loggingService->addLogEntry( - new UnknownEntityLog( - $this->runId, - DefaultEntities::COUNTRY_STATE, - $oldAddressData['stateID'] ?? 'unknown', - DefaultEntities::ORDER, - $this->oldId - ) + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(OrderAddressDefinition::ENTITY_NAME) + ->withFieldName('countryStateId') + ->withFieldSourcePath('stateID') + ->withSourceData($oldAddressData) + ->build(UnknownEntityLog::class) ); return []; @@ -696,19 +633,18 @@ protected function getCountryState(array $oldAddressData, string $newCountryId): $oldAddressData['state']['active'] )) { $this->loggingService->addLogEntry( - new UnknownEntityLog( - $this->runId, - DefaultEntities::COUNTRY_STATE, - $oldAddressData['stateID'], - DefaultEntities::ORDER, - $this->oldId - ) + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(OrderAddressDefinition::ENTITY_NAME) + ->withFieldName('countryStateId') + ->withFieldSourcePath('name') + ->withSourceData($oldAddressData['state']) + ->build(UnknownEntityLog::class) ); return []; } - $state['id'] = $mapping['entityUuid']; + $state['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $oldStateData = $oldAddressData['state']; @@ -749,7 +685,7 @@ protected function applyCountryStateTranslation(array &$state, array $data): voi $data['id'] . ':' . $this->mainLocale, $this->context ); - $localeTranslation['id'] = $mapping['entityUuid']; + $localeTranslation['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $languageUuid = $this->languageLookup->get($this->mainLocale, $this->context); @@ -768,21 +704,26 @@ protected function applyCountryStateTranslation(array &$state, array $data): voi protected function getDeliveries(array $data, array $converted, CalculatedPrice $shippingCosts): array { $deliveries = []; - $deliveryStateMapping = $this->mappingService->getMapping( - $this->connectionId, - OrderDeliveryStateReader::getMappingName(), - (string) $data['status'], - $this->context - ); + $deliveryStateMapping = null; + if (isset($data['status'])) { + $deliveryStateMapping = $this->mappingService->getMapping( + $this->connectionId, + OrderDeliveryStateReader::getMappingName(), + (string) $data['status'], + $this->context + ); + } if ($deliveryStateMapping === null) { - $this->loggingService->addLogEntry(new UnknownEntityLog( - $this->runId, - 'order_delivery_state', - (string) $data['status'], - DefaultEntities::ORDER, - $this->oldId - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(OrderDeliveryDefinition::ENTITY_NAME) + ->withFieldName('stateId') + ->withFieldSourcePath('status') + ->withSourceData($data) + ->withConvertedData($converted) + ->build(UnknownEntityLog::class) + ); return []; } @@ -797,8 +738,8 @@ protected function getDeliveries(array $data, array $converted, CalculatedPrice $this->mappingIds[] = $mapping['id']; $delivery = [ - 'id' => $mapping['entityUuid'], - 'stateId' => $deliveryStateMapping['entityUuid'], + 'id' => $mapping['entityId'], + 'stateId' => $deliveryStateMapping['entityId'], 'shippingDateEarliest' => $converted['orderDateTime'], 'shippingDateLatest' => $converted['orderDateTime'], ]; @@ -834,7 +775,7 @@ protected function getDeliveries(array $data, array $converted, CalculatedPrice ); $this->mappingIds[] = $mapping['id']; $positions[] = [ - 'id' => $mapping['entityUuid'], + 'id' => $mapping['entityId'], 'orderLineItemId' => $lineItem['id'], 'price' => $lineItem['price'], ]; @@ -859,19 +800,20 @@ protected function getShippingMethod(string $shippingMethodId): ?string ); if ($shippingMethodMapping === null) { - $this->loggingService->addLogEntry(new UnknownEntityLog( - $this->runId, - DefaultEntities::SHIPPING_METHOD, - $shippingMethodId, - DefaultEntities::ORDER, - $this->oldId - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(OrderDeliveryDefinition::ENTITY_NAME) + ->withFieldName('shippingMethodId') + ->withFieldSourcePath('dispatchID') + ->withSourceData(['dispatchID' => $shippingMethodId]) + ->build(UnknownEntityLog::class) + ); return null; } $this->mappingIds[] = $shippingMethodMapping['id']; - return $shippingMethodMapping['entityUuid']; + return $shippingMethodMapping['entityId']; } /** @@ -895,8 +837,8 @@ protected function getLineItems(array $originalData, TaxRuleCollection $taxRules $this->mappingIds[] = $mapping['id']; $lineItem = [ - 'id' => $mapping['entityUuid'], - 'identifier' => $mapping['entityUuid'], + 'id' => $mapping['entityId'], + 'identifier' => $mapping['entityId'], ]; if ($isProduct) { @@ -909,8 +851,8 @@ protected function getLineItems(array $originalData, TaxRuleCollection $taxRules ); if ($mapping !== null) { - $lineItem['referencedId'] = $mapping['entityUuid']; - $lineItem['productId'] = $mapping['entityUuid']; + $lineItem['referencedId'] = $mapping['entityId']; + $lineItem['productId'] = $mapping['entityId']; $lineItem['payload']['productNumber'] = $originalLineItem['articleordernumber'] ?? ''; $this->mappingIds[] = $mapping['id']; } @@ -1026,20 +968,21 @@ protected function getSalutation(string $salutation): ?string ); if ($salutationMapping === null) { - $this->loggingService->addLogEntry(new UnknownEntityLog( - $this->runId, - 'salutation', - $salutation, - DefaultEntities::ORDER, - $this->oldId - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(OrderAddressDefinition::ENTITY_NAME) + ->withFieldName('salutationId') + ->withFieldSourcePath('salutation') + ->withSourceData(['salutation' => $salutation]) + ->build(UnknownEntityLog::class) + ); return null; } $this->mappingIds[] = $salutationMapping['id']; - return $salutationMapping['entityUuid']; + return $salutationMapping['entityId']; } /** @@ -1057,13 +1000,14 @@ private function getOrderLineItemDownload(array $originalEsdItem): ?array ); if (!\is_array($mediaMapping)) { - $this->loggingService->addLogEntry(new UnknownEntityLog( - $this->runId, - 'product_download_media', - $originalEsdItem['esdID'], - DefaultEntities::ORDER, - $this->oldId - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(OrderLineItemDefinition::ENTITY_NAME) + ->withFieldName('coverId') + ->withFieldSourcePath('esd.esdID') + ->withSourceData($originalEsdItem) + ->build(UnknownEntityLog::class) + ); return null; } @@ -1087,8 +1031,8 @@ private function getOrderLineItemDownload(array $originalEsdItem): ?array } return [ - 'id' => $mapping['entityUuid'], - 'mediaId' => $mediaMapping['entityUuid'], + 'id' => $mapping['entityId'], + 'mediaId' => $mediaMapping['entityId'], 'accessGranted' => $accessGranted, 'position' => 0, ]; diff --git a/src/Profile/Shopware/Converter/OrderDocumentConverter.php b/src/Profile/Shopware/Converter/OrderDocumentConverter.php index 0d098333d..f3590b14f 100644 --- a/src/Profile/Shopware/Converter/OrderDocumentConverter.php +++ b/src/Profile/Shopware/Converter/OrderDocumentConverter.php @@ -15,9 +15,8 @@ use Shopware\Core\Framework\Util\Random; use SwagMigrationAssistant\Migration\Converter\ConvertStruct; use SwagMigrationAssistant\Migration\DataSelection\DefaultEntities; -use SwagMigrationAssistant\Migration\Logging\Log\AssociationRequiredMissingLog; -use SwagMigrationAssistant\Migration\Logging\Log\DocumentTypeNotSupported; -use SwagMigrationAssistant\Migration\Logging\Log\EmptyNecessaryFieldRunLog; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogBuilder; +use SwagMigrationAssistant\Migration\Logging\Log\DocumentTypeNotSupportedLog; use SwagMigrationAssistant\Migration\Logging\LoggingServiceInterface; use SwagMigrationAssistant\Migration\Mapping\Lookup\DocumentTypeLookup; use SwagMigrationAssistant\Migration\Mapping\Lookup\MediaDefaultFolderLookup; @@ -72,42 +71,11 @@ public function convert(array $data, Context $context, MigrationContextInterface $this->context = $context; $connection = $migrationContext->getConnection(); - $this->connectionName = ''; - $this->connectionId = ''; - if ($connection !== null) { - $this->connectionId = $connection->getId(); - $this->connectionName = $connection->getName(); - } + $this->connectionId = $connection->getId(); + $this->connectionName = $connection->getName(); - $oldData = $data; $converted = []; - if (empty($data['hash'])) { - $this->loggingService->addLogEntry( - new EmptyNecessaryFieldRunLog( - $this->migrationContext->getRunUuid(), - DefaultEntities::ORDER_DOCUMENT, - $this->oldId, - 'hash' - ) - ); - - return new ConvertStruct(null, $oldData); - } - - if (!isset($data['documenttype'])) { - $this->loggingService->addLogEntry( - new EmptyNecessaryFieldRunLog( - $this->migrationContext->getRunUuid(), - DefaultEntities::ORDER_DOCUMENT, - $this->oldId, - 'documenttype' - ) - ); - - return new ConvertStruct(null, $oldData); - } - $orderMapping = $this->mappingService->getMapping( $this->connectionId, DefaultEntities::ORDER, @@ -115,21 +83,11 @@ public function convert(array $data, Context $context, MigrationContextInterface $context ); - if ($orderMapping === null) { - $this->loggingService->addLogEntry( - new AssociationRequiredMissingLog( - $this->migrationContext->getRunUuid(), - DefaultEntities::ORDER, - $this->oldId, - DefaultEntities::ORDER_DOCUMENT - ) - ); - - return new ConvertStruct(null, $oldData); + if ($orderMapping !== null) { + $this->mappingIds[] = $orderMapping['id']; + $converted['orderId'] = $orderMapping['entityId']; } unset($data['orderID']); - $orderUuid = $orderMapping['entityUuid']; - $this->mappingIds[] = $orderMapping['id']; $this->mainMapping = $this->mappingService->getOrCreateMapping( $this->connectionId, @@ -138,27 +96,27 @@ public function convert(array $data, Context $context, MigrationContextInterface $context, $this->checksum ); - $converted['id'] = $this->mainMapping['entityUuid']; - $converted['orderId'] = $orderUuid; + + $converted['id'] = $this->mainMapping['entityId']; $converted['fileType'] = FileTypes::PDF; $converted['static'] = true; $converted['deepLinkCode'] = Random::getAlphanumericString(32); $converted['config'] = []; + if (isset($data['docID'])) { $converted['config']['documentNumber'] = $data['docID']; + if (isset($data['documenttype'])) { + $converted['documentType'] = $this->getDocumentType($data['documenttype']); + } + if (isset($data['documenttype']['key']) && $data['documenttype']['key'] === 'invoice') { $converted['config']['custom']['invoiceNumber'] = $data['docID']; } - unset($data['docID']); + unset($data['docID'], $data['documenttype']); } - $documentType = $this->getDocumentType($data['documenttype']); - - $converted['documentType'] = $documentType; - unset($data['documenttype']); - if (isset($data['attributes'])) { $converted['customFields'] = $this->getAttributes($data['attributes'], DefaultEntities::ORDER_DOCUMENT, $this->connectionName, ['id', 'documentID'], $this->context); } @@ -202,11 +160,15 @@ protected function getDocumentType(array $data): array return $documentType; } - $this->loggingService->addLogEntry(new DocumentTypeNotSupported( - $this->runId, - $data['id'], - $mappedKey - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(DocumentDefinition::ENTITY_NAME) + ->withFieldName('documentType') + ->withFieldSourcePath('key') + ->withSourceData($data) + ->withConvertedData($documentType) + ->build(DocumentTypeNotSupportedLog::class) + ); $mapping = $this->mappingService->getOrCreateMapping( $this->connectionId, @@ -216,7 +178,7 @@ protected function getDocumentType(array $data): array ); $this->mappingIds[] = $mapping['id']; - $documentType['id'] = $mapping['entityUuid']; + $documentType['id'] = $mapping['entityId']; $documentType['name'] = $data['name']; $documentType['technicalName'] = $mappedKey; @@ -238,19 +200,21 @@ protected function getMediaFile(array $data): array ); $newMedia = []; - $newMedia['id'] = $mapping['entityUuid']; + $newMedia['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; - $this->mediaFileService->saveMediaFile( - [ - 'runId' => $this->runId, - 'entity' => OrderDocumentDataSet::getEntity(), - 'uri' => $data['hash'], - 'fileName' => $data['hash'], - 'fileSize' => 0, - 'mediaId' => $newMedia['id'], - ] - ); + if (!empty($data['hash'])) { + $this->mediaFileService->saveMediaFile( + [ + 'runId' => $this->runId, + 'entity' => OrderDocumentDataSet::getEntity(), + 'uri' => $data['hash'], + 'fileName' => $data['hash'], + 'fileSize' => 0, + 'mediaId' => $newMedia['id'], + ] + ); + } $newMedia['private'] = true; $this->convertValue($newMedia, 'title', $data, 'hash'); diff --git a/src/Profile/Shopware/Converter/ProductConverter.php b/src/Profile/Shopware/Converter/ProductConverter.php index 1a4d04fc3..9499ec730 100644 --- a/src/Profile/Shopware/Converter/ProductConverter.php +++ b/src/Profile/Shopware/Converter/ProductConverter.php @@ -7,18 +7,24 @@ namespace SwagMigrationAssistant\Profile\Shopware\Converter; +use Shopware\Core\Content\Media\MediaDefinition; use Shopware\Core\Content\Product\Aggregate\ProductDownload\ProductDownloadDefinition; +use Shopware\Core\Content\Product\Aggregate\ProductMedia\ProductMediaDefinition; +use Shopware\Core\Content\Product\Aggregate\ProductPrice\ProductPriceDefinition; use Shopware\Core\Content\Product\Aggregate\ProductVisibility\ProductVisibilityDefinition; +use Shopware\Core\Content\Product\ProductDefinition; use Shopware\Core\Defaults; use Shopware\Core\Framework\Context; use Shopware\Core\Framework\Log\Package; use Shopware\Core\Framework\Rule\Container\AndRule; use Shopware\Core\Framework\Rule\Container\OrRule; +use Shopware\Core\Framework\Util\Hasher; use Shopware\Core\Framework\Uuid\Uuid; use SwagMigrationAssistant\Exception\MigrationException; use SwagMigrationAssistant\Migration\Converter\ConvertStruct; use SwagMigrationAssistant\Migration\DataSelection\DefaultEntities; -use SwagMigrationAssistant\Migration\Logging\Log\CannotConvertChildEntity; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogBuilder; +use SwagMigrationAssistant\Migration\Logging\Log\CannotConvertChildEntityLog; use SwagMigrationAssistant\Migration\Logging\Log\EmptyNecessaryFieldRunLog; use SwagMigrationAssistant\Migration\Logging\LoggingServiceInterface; use SwagMigrationAssistant\Migration\Mapping\Lookup\DeliveryTimeLookup; @@ -45,14 +51,6 @@ abstract class ProductConverter extends ShopwareConverter protected string $runId; - /** - * @var list - */ - protected array $requiredDataFieldKeys = [ - 'tax', - 'prices', - ]; - /** * @var array{minPurchase: int, purchaseSteps: int, shippingFree: bool, restockTime: int} */ @@ -137,24 +135,8 @@ public function convert( $this->locale = $data['_locale']; $connection = $migrationContext->getConnection(); - $this->connectionName = ''; - $this->connectionId = ''; - if ($connection !== null) { - $this->connectionId = $connection->getId(); - $this->connectionName = $connection->getName(); - } - - $fields = $this->checkForEmptyRequiredDataFields($data, $this->requiredDataFieldKeys); - if (!empty($fields)) { - $this->loggingService->addLogEntry(new EmptyNecessaryFieldRunLog( - $this->runId, - DefaultEntities::PRODUCT, - $this->oldProductId, - \implode(',', $fields) - )); - - return new ConvertStruct(null, $data); - } + $this->connectionId = $connection->getId(); + $this->connectionName = $connection->getName(); $this->productType = (int) $data['detail']['kind']; unset($data['detail']['kind']); @@ -209,7 +191,7 @@ protected function convertMainProduct(array $data): ConvertStruct $data['id'], $this->context ); - $containerUuid = $containerMapping['entityUuid']; + $containerUuid = $containerMapping['entityId']; $converted = []; $converted['id'] = $containerUuid; @@ -229,7 +211,7 @@ protected function convertMainProduct(array $data): ConvertStruct $this->context, $this->checksum ); - $converted['children'][0]['id'] = $this->mainMapping['entityUuid']; + $converted['children'][0]['id'] = $this->mainMapping['entityId']; if (isset($converted['children'][0]['media'])) { if (isset($converted['children'][0]['cover'])) { @@ -242,9 +224,9 @@ protected function convertMainProduct(array $data): ConvertStruct $media['id'], $this->context ); - $productMediaRelationUuid = $productMediaRelationMapping['entityUuid']; + $productMediaRelationUuid = $productMediaRelationMapping['entityId']; $this->mappingIds[] = $productMediaRelationMapping['id']; - $media['productId'] = $this->mainMapping['entityUuid']; + $media['productId'] = $this->mainMapping['entityId']; $media['id'] = $productMediaRelationUuid; if (isset($coverMediaUuid) && $media['media']['id'] === $coverMediaUuid) { @@ -305,8 +287,8 @@ protected function convertVariantProduct(array $data): ConvertStruct ); $converted = []; - $converted['id'] = $this->mainMapping['entityUuid']; - $converted['parentId'] = $parentMapping['entityUuid']; + $converted['id'] = $this->mainMapping['entityId']; + $converted['parentId'] = $parentMapping['entityId']; $this->mappingIds[] = $parentMapping['id']; $converted = $this->getProductData($data, $converted); unset($data['detail']['id'], $data['detail']['articleID'], $data['categories']); @@ -342,7 +324,7 @@ private function getUuidForProduct(array &$data): array ); $converted = []; - $converted['id'] = $this->mainMapping['entityUuid']; + $converted['id'] = $this->mainMapping['entityId']; $mapping = $this->mappingService->getOrCreateMapping( $this->connectionId, @@ -387,12 +369,15 @@ private function getProductData(array &$data, array $converted): array $converted['price'] = $this->getPrice($data['prices'][0], $converted['tax']['taxRate']); if (empty($converted['price'])) { - $this->loggingService->addLogEntry(new EmptyNecessaryFieldRunLog( - $this->runId, - DefaultEntities::PRODUCT, - $this->oldProductId, - 'currency' - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(ProductDefinition::ENTITY_NAME) + ->withFieldName('price') + ->withFieldSourcePath('prices') + ->withSourceData($data) + ->withConvertedData($converted) + ->build(EmptyNecessaryFieldRunLog::class) + ); } $converted['prices'] = $this->getPrices($data['prices'], $converted); @@ -605,7 +590,7 @@ private function getDeliveryTime(string $shippingTime): ?array ); if ($mapping !== null) { - $convertedDeliveryTime['id'] = $mapping['entityUuid']; + $convertedDeliveryTime['id'] = $mapping['entityId']; return $convertedDeliveryTime; } @@ -666,21 +651,21 @@ private function applyOptions(array &$converted, array &$data): void $optionMapping = $this->mappingService->getOrCreateMapping( $this->connectionId, DefaultEntities::PROPERTY_GROUP_OPTION, - \hash('md5', \mb_strtolower($option['name'] . '_' . $option['group']['name'])), + Hasher::hash(\mb_strtolower($option['name'] . '_' . $option['group']['name']), 'md5'), $this->context ); $this->mappingIds[] = $optionMapping['id']; $optionGroupMapping = $this->mappingService->getOrCreateMapping( $this->connectionId, DefaultEntities::PROPERTY_GROUP, - \hash('md5', \mb_strtolower($option['group']['name'])), + Hasher::hash(\mb_strtolower($option['group']['name']), 'md5'), $this->context ); $this->mappingIds[] = $optionGroupMapping['id']; $optionElement = [ - 'id' => $optionMapping['entityUuid'], + 'id' => $optionMapping['entityId'], 'group' => [ - 'id' => $optionGroupMapping['entityUuid'], + 'id' => $optionGroupMapping['entityId'], ], ]; @@ -715,7 +700,7 @@ private function getManufacturer(array $data): array $this->context ); $manufacturer = []; - $manufacturer['id'] = $mapping['entityUuid']; + $manufacturer['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $this->applyManufacturerTranslation($manufacturer, $data); @@ -762,7 +747,7 @@ private function applyManufacturerTranslation(array &$manufacturer, array $data) $data['id'] . ':' . $this->locale, $this->context ); - $localeTranslation['id'] = $mapping['entityUuid']; + $localeTranslation['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $languageUuid = $this->languageLookup->get($this->locale, $this->context); @@ -788,7 +773,7 @@ private function getTax(array $taxData): array $taxData['id'], $this->context ); - $taxUuid = $mapping['entityUuid']; + $taxUuid = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; } @@ -813,7 +798,7 @@ private function getUnit(array $data): array $data['id'], $this->context ); - $unit['id'] = $mapping['entityUuid']; + $unit['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $this->applyUnitTranslation($unit, $data); @@ -850,7 +835,7 @@ private function applyUnitTranslation(array &$unit, array $data): void $data['id'] . ':' . $this->locale, $this->context ); - $localeTranslation['id'] = $mapping['entityUuid']; + $localeTranslation['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $languageUuid = $this->languageLookup->get($this->locale, $this->context); @@ -877,7 +862,7 @@ private function getEsdFiles(array $esdFiles, string $oldVariantId, array $conve $oldVariantId . '_' . $esdFile['id'], $this->context ); - $newProductMedia['id'] = $mapping['entityUuid']; + $newProductMedia['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $newProductMedia['productId'] = $converted['id']; @@ -890,28 +875,36 @@ private function getEsdFiles(array $esdFiles, string $oldVariantId, array $conve $this->context ); - $newMedia['id'] = $mapping['entityUuid']; + $newMedia['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; + if (empty($esdFile['name'])) { - $this->loggingService->addLogEntry(new CannotConvertChildEntity( - $this->runId, - DefaultEntities::PRODUCT_DOWNLOAD, - DefaultEntities::PRODUCT, - $this->oldProductId - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(MediaDefinition::ENTITY_NAME) + ->withFieldName('name') + ->withFieldSourcePath('name') + ->withSourceData($esdFile) + ->withConvertedData($newMedia) + ->build(CannotConvertChildEntityLog::class) + ); continue; } try { $path = \unserialize($esdFile['path'], ['allowed_classes' => false]); - } catch (\Throwable $error) { - $this->loggingService->addLogEntry(new CannotConvertChildEntity( - $this->runId, - DefaultEntities::PRODUCT_DOWNLOAD, - DefaultEntities::PRODUCT, - $this->oldProductId - )); + } catch (\Throwable $e) { + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(MediaDefinition::ENTITY_NAME) + ->withFieldName('path') + ->withFieldSourcePath('path') + ->withSourceData($esdFile) + ->withExceptionMessage($e->getMessage()) + ->withExceptionTrace($e->getTrace()) + ->build(CannotConvertChildEntityLog::class) + ); continue; } @@ -927,17 +920,29 @@ private function getEsdFiles(array $esdFiles, string $oldVariantId, array $conve ] ); - $esdFile['name'] = \pathinfo($esdFile['name'], \PATHINFO_FILENAME); - $this->convertValue($newMedia, 'title', $esdFile, 'name'); + $fileName = \pathinfo($esdFile['name'], \PATHINFO_FILENAME); + $sourceData = ['name' => $fileName]; + + $this->convertValue( + $newMedia, + 'title', + $sourceData, + 'name' + ); $albumId = $this->mediaFolderLookup->get(ProductDownloadDefinition::ENTITY_NAME, $this->context); if ($albumId === null) { - $this->loggingService->addLogEntry(new CannotConvertChildEntity( - $this->runId, - DefaultEntities::PRODUCT_DOWNLOAD, - DefaultEntities::PRODUCT, - $this->oldProductId - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(MediaDefinition::ENTITY_NAME) + ->withFieldName('mediaFolderId') + ->withSourceData([ + 'file_name' => $fileName, + 'source_data' => $sourceData, + 'media_folder' => ProductDownloadDefinition::ENTITY_NAME, + ]) + ->build(CannotConvertChildEntityLog::class) + ); continue; } @@ -966,12 +971,14 @@ private function getMedia(array $media, string $oldVariantId, array $converted): $mediaObjects = []; foreach ($media as $mediaData) { if (!isset($mediaData['media']['id'])) { - $this->loggingService->addLogEntry(new CannotConvertChildEntity( - $this->runId, - DefaultEntities::PRODUCT_MEDIA, - DefaultEntities::PRODUCT, - $this->oldProductId - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(ProductMediaDefinition::ENTITY_NAME) + ->withFieldName('mediaId') + ->withFieldSourcePath('media.id') + ->withSourceData($mediaData) + ->build(CannotConvertChildEntityLog::class) + ); continue; } @@ -983,7 +990,7 @@ private function getMedia(array $media, string $oldVariantId, array $converted): $oldVariantId . $mediaData['id'], $this->context ); - $newProductMedia['id'] = $mapping['entityUuid']; + $newProductMedia['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $newProductMedia['productId'] = $converted['id']; $this->convertValue($newProductMedia, 'position', $mediaData, 'position', self::TYPE_INTEGER); @@ -995,7 +1002,7 @@ private function getMedia(array $media, string $oldVariantId, array $converted): $mediaData['media']['id'], $this->context ); - $newMedia['id'] = $mapping['entityUuid']; + $newMedia['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; if (empty($mediaData['media']['name'])) { @@ -1025,7 +1032,7 @@ private function getMedia(array $media, string $oldVariantId, array $converted): ); if ($albumMapping !== null) { - $newMedia['mediaFolderId'] = $albumMapping['entityUuid']; + $newMedia['mediaFolderId'] = $albumMapping['entityId']; $this->mappingIds[] = $albumMapping['id']; } @@ -1127,7 +1134,7 @@ private function applyMediaTranslation(array &$media, array $data): void $data['media']['id'] . ':' . $this->locale, $this->context ); - $localeTranslation['id'] = $mapping['entityUuid']; + $localeTranslation['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $languageUuid = $this->languageLookup->get($this->locale, $this->context); @@ -1151,7 +1158,7 @@ private function getManufacturerMedia(array $media): array $this->context ); $manufacturerMedia = []; - $manufacturerMedia['id'] = $mapping['entityUuid']; + $manufacturerMedia['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; if (empty($media['name'])) { @@ -1168,7 +1175,7 @@ private function getManufacturerMedia(array $media): array ); if ($albumMapping !== null) { - $manufacturerMedia['mediaFolderId'] = $albumMapping['entityUuid']; + $manufacturerMedia['mediaFolderId'] = $albumMapping['entityId']; $this->mappingIds[] = $albumMapping['id']; } @@ -1200,10 +1207,10 @@ private function applyOptionTranslation(array &$option, array $data): void $mapping = $this->mappingService->getOrCreateMapping( $this->connectionId, DefaultEntities::PROPERTY_GROUP_OPTION_TRANSLATION, - \hash('md5', \mb_strtolower($data['name'] . '_' . $data['group']['name'])) . ':' . $this->locale, + Hasher::hash(\mb_strtolower($data['name'] . '_' . $data['group']['name']), 'md5') . ':' . $this->locale, $this->context ); - $localeOptionTranslation['id'] = $mapping['entityUuid']; + $localeOptionTranslation['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $this->convertValue($localeOptionTranslation, 'name', $data, 'name'); @@ -1212,10 +1219,10 @@ private function applyOptionTranslation(array &$option, array $data): void $mapping = $this->mappingService->getOrCreateMapping( $this->connectionId, DefaultEntities::PROPERTY_GROUP_TRANSLATION, - \hash('md5', \mb_strtolower($data['group']['name'])) . ':' . $this->locale, + Hasher::hash(\mb_strtolower($data['group']['name']), 'md5') . ':' . $this->locale, $this->context ); - $localeGroupTranslation['id'] = $mapping['entityUuid']; + $localeGroupTranslation['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $this->convertValue($localeGroupTranslation, 'name', $data['group'], 'name'); @@ -1247,7 +1254,7 @@ private function getPrice(array $priceData, float $taxRate): array if (!isset($currencyMapping)) { return []; } - $this->currencyUuid = $currencyMapping['entityUuid']; + $this->currencyUuid = $currencyMapping['entityId']; $this->mappingIds[] = $currencyMapping['id']; $price = []; @@ -1305,7 +1312,7 @@ private function getPrices(array $priceData, array $converted): array if ($customerGroupMapping === null) { continue; } - $customerGroupUuid = $customerGroupMapping['entityUuid']; + $customerGroupUuid = $customerGroupMapping['entityId']; $this->mappingIds[] = $customerGroupMapping['id']; $mapping = $this->mappingService->getOrCreateMapping( @@ -1314,7 +1321,7 @@ private function getPrices(array $priceData, array $converted): array 'customerGroupRule_productPriceRule_' . $price['id'] . '_' . $price['customergroup']['id'], $this->context ); - $productPriceRuleUuid = $mapping['entityUuid']; + $productPriceRuleUuid = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $mapping = $this->mappingService->getOrCreateMapping( @@ -1323,7 +1330,7 @@ private function getPrices(array $priceData, array $converted): array 'customerGroupRule_' . $price['customergroup']['id'], $this->context ); - $priceRuleUuid = $mapping['entityUuid']; + $priceRuleUuid = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $mapping = $this->mappingService->getOrCreateMapping( @@ -1332,7 +1339,7 @@ private function getPrices(array $priceData, array $converted): array 'customerGroupRule_orContainer_' . $price['customergroup']['id'], $this->context ); - $orContainerUuid = $mapping['entityUuid']; + $orContainerUuid = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $mapping = $this->mappingService->getOrCreateMapping( @@ -1341,7 +1348,7 @@ private function getPrices(array $priceData, array $converted): array 'customerGroupRule_andContainer_' . $price['customergroup']['id'], $this->context ); - $andContainerUuid = $mapping['entityUuid']; + $andContainerUuid = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $mapping = $this->mappingService->getOrCreateMapping( @@ -1350,18 +1357,21 @@ private function getPrices(array $priceData, array $converted): array 'customerGroupRule_condition_' . $price['customergroup']['id'], $this->context ); - $conditionUuid = $mapping['entityUuid']; + $conditionUuid = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $priceArray = $this->getPrice($price, $converted['tax']['taxRate']); if (empty($priceArray)) { - $this->loggingService->addLogEntry(new EmptyNecessaryFieldRunLog( - $this->runId, - DefaultEntities::PRODUCT_PRICE, - $this->oldProductId, - 'currencyId' - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(ProductPriceDefinition::ENTITY_NAME) + ->withFieldName('price') + ->withFieldSourcePath('price') + ->withSourceData($price) + ->withConvertedData($converted) + ->build(EmptyNecessaryFieldRunLog::class) + ); continue; } @@ -1492,14 +1502,14 @@ private function createMainCategoriesMapping(array $categories): array DefaultEntities::CATEGORY, $category['categoryId'], $this->context - )['entityUuid']; + )['entityId']; $salesChannelId = $this->mappingService->getOrCreateMapping( $this->connectionId, DefaultEntities::SALES_CHANNEL, $category['shopId'], $this->context - )['entityUuid']; + )['entityId']; if (!$categoryId || !$salesChannelId) { continue; @@ -1534,7 +1544,7 @@ private function getCategoryMapping(array $categories): array if ($mapping === null) { continue; } - $categoryMapping[] = ['id' => (string) $mapping['entityUuid']]; + $categoryMapping[] = ['id' => (string) $mapping['entityId']]; $this->mappingIds[] = $mapping['id']; } @@ -1560,7 +1570,7 @@ private function getVisibilities(array $converted, array $shops): array ); if ($mapping !== null) { - $salesChannelUuid = (string) $mapping['entityUuid']; + $salesChannelUuid = (string) $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $mapping = $this->mappingService->getOrCreateMapping( $this->connectionId, @@ -1570,7 +1580,7 @@ private function getVisibilities(array $converted, array $shops): array ); $this->mappingIds[] = $mapping['id']; $visibilities[] = [ - 'id' => (string) $mapping['entityUuid'], + 'id' => (string) $mapping['entityId'], 'productId' => $converted['id'], 'salesChannelId' => $salesChannelUuid, 'visibility' => ProductVisibilityDefinition::VISIBILITY_ALL, diff --git a/src/Profile/Shopware/Converter/ProductOptionRelationConverter.php b/src/Profile/Shopware/Converter/ProductOptionRelationConverter.php index 587823a86..2da20c296 100644 --- a/src/Profile/Shopware/Converter/ProductOptionRelationConverter.php +++ b/src/Profile/Shopware/Converter/ProductOptionRelationConverter.php @@ -9,6 +9,7 @@ use Shopware\Core\Framework\Context; use Shopware\Core\Framework\Log\Package; +use Shopware\Core\Framework\Util\Hasher; use SwagMigrationAssistant\Migration\Converter\ConvertStruct; use SwagMigrationAssistant\Migration\DataSelection\DefaultEntities; use SwagMigrationAssistant\Migration\MigrationContextInterface; @@ -34,10 +35,7 @@ public function convert(array $data, Context $context, MigrationContextInterface $this->originalData = $data; $connection = $migrationContext->getConnection(); - $this->connectionId = ''; - if ($connection !== null) { - $this->connectionId = $connection->getId(); - } + $this->connectionId = $connection->getId(); $productContainerMapping = $this->mappingService->getMapping( $this->connectionId, @@ -46,29 +44,16 @@ public function convert(array $data, Context $context, MigrationContextInterface $context ); - if ($productContainerMapping === null) { - return new ConvertStruct(null, $this->originalData); - } - $this->mappingIds[] = $productContainerMapping['id']; - - $optionMapping = $this->mappingService->getMapping( - $this->connectionId, - DefaultEntities::PROPERTY_GROUP_OPTION, - \hash('md5', \mb_strtolower($data['name'] . '_' . $data['group']['name'])), - $context - ); - - if ($optionMapping === null) { - return new ConvertStruct(null, $this->originalData); + $relationMapping = null; + if ($productContainerMapping !== null) { + $this->mappingIds[] = $productContainerMapping['id']; + $relationMapping = $this->mappingService->getMapping( + $this->connectionId, + DefaultEntities::PRODUCT_PROPERTY, + $data['id'] . '_' . $productContainerMapping['entityId'], + $context + ); } - $this->mappingIds[] = $optionMapping['id']; - - $relationMapping = $this->mappingService->getMapping( - $this->connectionId, - DefaultEntities::PRODUCT_PROPERTY, - $data['id'] . '_' . $productContainerMapping['entityUuid'], - $context - ); // use "old" relation mapping if exists < v.1.3 if ($relationMapping !== null) { @@ -79,7 +64,7 @@ public function convert(array $data, Context $context, MigrationContextInterface $context, null, null, - $relationMapping['entityUuid'] + $relationMapping['entityId'] ); } else { $this->mainMapping = $this->mappingService->getOrCreateMapping( @@ -90,12 +75,27 @@ public function convert(array $data, Context $context, MigrationContextInterface ); } + $optionMapping = $this->mappingService->getMapping( + $this->connectionId, + DefaultEntities::PROPERTY_GROUP_OPTION, + Hasher::hash(\mb_strtolower($data['name'] . '_' . $data['group']['name']), 'md5'), + $context + ); + $converted = []; - $converted['id'] = $productContainerMapping['entityUuid']; - $converted['configuratorSettings'][] = [ - 'id' => $this->mainMapping['entityUuid'], - 'optionId' => $optionMapping['entityUuid'], - ]; + + if ($optionMapping !== null) { + $this->mappingIds[] = $optionMapping['id']; + $converted['configuratorSettings'][] = [ + 'id' => $this->mainMapping['entityId'], + 'optionId' => $optionMapping['entityId'], + ]; + } + + if (isset($productContainerMapping['entityId'])) { + $converted['id'] = $productContainerMapping['entityId']; + } + $this->updateMainMapping($migrationContext, $context); return new ConvertStruct($converted, null, $this->mainMapping['id'] ?? null); diff --git a/src/Profile/Shopware/Converter/ProductPropertyRelationConverter.php b/src/Profile/Shopware/Converter/ProductPropertyRelationConverter.php index e1b25099c..75d6c9289 100644 --- a/src/Profile/Shopware/Converter/ProductPropertyRelationConverter.php +++ b/src/Profile/Shopware/Converter/ProductPropertyRelationConverter.php @@ -9,6 +9,7 @@ use Shopware\Core\Framework\Context; use Shopware\Core\Framework\Log\Package; +use Shopware\Core\Framework\Util\Hasher; use SwagMigrationAssistant\Migration\Converter\ConvertStruct; use SwagMigrationAssistant\Migration\DataSelection\DefaultEntities; use SwagMigrationAssistant\Migration\MigrationContextInterface; @@ -37,11 +38,9 @@ public function convert(array $data, Context $context, MigrationContextInterface $this->originalData = $data; $connection = $migrationContext->getConnection(); - $this->connectionId = ''; - if ($connection !== null) { - $this->connectionId = $connection->getId(); - } + $this->connectionId = $connection->getId(); + $converted = []; $productMapping = $this->mappingService->getMapping( $this->connectionId, DefaultEntities::PRODUCT_CONTAINER, @@ -56,23 +55,28 @@ public function convert(array $data, Context $context, MigrationContextInterface $data['productId'], $context ); + } - if ($productMapping === null) { - return new ConvertStruct(null, $this->originalData); - } + if ($productMapping !== null) { + $this->mappingIds[] = $productMapping['id']; + $converted['id'] = $productMapping['entityId']; } - $this->mappingIds[] = $productMapping['id']; + $optionMapping = $this->mappingService->getMapping( $this->connectionId, DefaultEntities::PROPERTY_GROUP_OPTION, - \hash('md5', \mb_strtolower($data['name'] . '_' . $data['group']['name'])), + Hasher::hash(\mb_strtolower($data['name'] . '_' . $data['group']['name']), 'md5'), $context ); - if ($optionMapping === null) { - return new ConvertStruct(null, $this->originalData); + if ($optionMapping !== null) { + $this->mappingIds[] = $optionMapping['id']; + + $converted['properties'][] = [ + 'id' => $optionMapping['entityId'], + ]; } - $this->mappingIds[] = $optionMapping['id']; + $this->mainMapping = $this->mappingService->getOrCreateMapping( $this->connectionId, DefaultEntities::PRODUCT_PROPERTY_RELATION, @@ -80,12 +84,6 @@ public function convert(array $data, Context $context, MigrationContextInterface $context ); - $converted = []; - $converted['id'] = $productMapping['entityUuid']; - $converted['properties'][] = [ - 'id' => $optionMapping['entityUuid'], - ]; - $this->updateMainMapping($migrationContext, $context); return new ConvertStruct($converted, null, $this->mainMapping['id'] ?? null); diff --git a/src/Profile/Shopware/Converter/ProductReviewConverter.php b/src/Profile/Shopware/Converter/ProductReviewConverter.php index ced4cac7c..c0efbc6bd 100644 --- a/src/Profile/Shopware/Converter/ProductReviewConverter.php +++ b/src/Profile/Shopware/Converter/ProductReviewConverter.php @@ -11,8 +11,6 @@ use Shopware\Core\Framework\Log\Package; use SwagMigrationAssistant\Migration\Converter\ConvertStruct; use SwagMigrationAssistant\Migration\DataSelection\DefaultEntities; -use SwagMigrationAssistant\Migration\Logging\Log\AssociationRequiredMissingLog; -use SwagMigrationAssistant\Migration\Logging\Log\EmptyNecessaryFieldRunLog; use SwagMigrationAssistant\Migration\Logging\LoggingServiceInterface; use SwagMigrationAssistant\Migration\Mapping\Lookup\LanguageLookup; use SwagMigrationAssistant\Migration\Mapping\MappingServiceInterface; @@ -21,14 +19,6 @@ #[Package('fundamentals@after-sales')] abstract class ProductReviewConverter extends ShopwareConverter { - /** - * @var list - */ - protected array $requiredDataFieldKeys = [ - '_locale', - 'articleID', - ]; - public function __construct( MappingServiceInterface $mappingService, LoggingServiceInterface $loggingService, @@ -39,27 +29,15 @@ public function __construct( public function convert(array $data, Context $context, MigrationContextInterface $migrationContext): ConvertStruct { - $fields = $this->checkForEmptyRequiredDataFields($data, $this->requiredDataFieldKeys); - - if (!empty($fields)) { - $this->loggingService->addLogEntry(new EmptyNecessaryFieldRunLog( - $migrationContext->getRunUuid(), - DefaultEntities::PRODUCT_REVIEW, - $data['id'], - \implode(',', $fields) - )); + $connection = $migrationContext->getConnection(); + $connectionId = $connection->getId(); - return new ConvertStruct(null, $data); - } $this->generateChecksum($data); - $originalData = $data; - $mainLocale = $data['_locale']; - unset($data['_locale']); - $connection = $migrationContext->getConnection(); - $connectionId = ''; - if ($connection !== null) { - $connectionId = $connection->getId(); + $mainLocale = null; + if (isset($data['_locale'])) { + $mainLocale = $data['_locale']; + unset($data['_locale']); } $converted = []; @@ -70,13 +48,14 @@ public function convert(array $data, Context $context, MigrationContextInterface $context, $this->checksum ); - $converted['id'] = $this->mainMapping['entityUuid']; + + $converted['id'] = $this->mainMapping['entityId']; unset($data['id']); $mapping = $this->mappingService->getMapping( $connectionId, DefaultEntities::PRODUCT_MAIN, - $data['articleID'], + $data['articleID'] ?? '', $context ); @@ -84,26 +63,16 @@ public function convert(array $data, Context $context, MigrationContextInterface $mapping = $this->mappingService->getMapping( $connectionId, DefaultEntities::PRODUCT_CONTAINER, - $data['articleID'], + $data['articleID'] ?? '', $context ); + } - if ($mapping === null) { - $this->loggingService->addLogEntry( - new AssociationRequiredMissingLog( - $migrationContext->getRunUuid(), - DefaultEntities::PRODUCT, - $data['articleID'], - DefaultEntities::PRODUCT_REVIEW - ) - ); - - return new ConvertStruct(null, $originalData); - } + if ($mapping !== null) { + $converted['productId'] = $mapping['entityId']; + $this->mappingIds[] = $mapping['id']; + unset($data['articleID']); } - $converted['productId'] = $mapping['entityUuid']; - $this->mappingIds[] = $mapping['id']; - unset($data['articleID']); if (isset($data['email'])) { $mapping = $this->mappingService->getMapping( @@ -114,10 +83,11 @@ public function convert(array $data, Context $context, MigrationContextInterface ); if ($mapping !== null) { - $converted['customerId'] = $mapping['entityUuid']; + $converted['customerId'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; } } + $this->convertValue($converted, 'externalEmail', $data, 'email'); $this->convertValue($converted, 'externalUser', $data, 'name'); @@ -129,35 +99,13 @@ public function convert(array $data, Context $context, MigrationContextInterface $context ); - if ($mapping === null) { - $this->loggingService->addLogEntry( - new AssociationRequiredMissingLog( - $migrationContext->getRunUuid(), - DefaultEntities::SALES_CHANNEL, - $shopId, - DefaultEntities::PRODUCT_REVIEW - ) - ); - - return new ConvertStruct(null, $originalData); + if ($mapping !== null) { + $converted['salesChannelId'] = $mapping['entityId']; + $this->mappingIds[] = $mapping['id']; + unset($data['shop_id'], $data['mainShopId']); } - $converted['salesChannelId'] = $mapping['entityUuid']; - $this->mappingIds[] = $mapping['id']; - unset($data['shop_id'], $data['mainShopId']); $converted['languageId'] = $this->languageLookup->get($mainLocale, $context); - if ($converted['languageId'] === null) { - $this->loggingService->addLogEntry( - new AssociationRequiredMissingLog( - $migrationContext->getRunUuid(), - DefaultEntities::LANGUAGE, - $mainLocale, - DefaultEntities::PRODUCT_REVIEW - ) - ); - - return new ConvertStruct(null, $originalData); - } $this->convertValue($converted, 'title', $data, 'headline'); if (empty($converted['title'])) { diff --git a/src/Profile/Shopware/Converter/PromotionConverter.php b/src/Profile/Shopware/Converter/PromotionConverter.php index e96286b0f..d79244961 100644 --- a/src/Profile/Shopware/Converter/PromotionConverter.php +++ b/src/Profile/Shopware/Converter/PromotionConverter.php @@ -7,7 +7,10 @@ namespace SwagMigrationAssistant\Profile\Shopware\Converter; +use Shopware\Core\Checkout\Promotion\Aggregate\PromotionCartRule\PromotionCartRuleDefinition; use Shopware\Core\Checkout\Promotion\Aggregate\PromotionDiscount\PromotionDiscountEntity; +use Shopware\Core\Checkout\Promotion\Aggregate\PromotionPersonaRule\PromotionPersonaRuleDefinition; +use Shopware\Core\Checkout\Promotion\PromotionDefinition; use Shopware\Core\Framework\Context; use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository; use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria; @@ -18,6 +21,7 @@ use SwagMigrationAssistant\Migration\Converter\ConvertStruct; use SwagMigrationAssistant\Migration\DataSelection\DefaultEntities; use SwagMigrationAssistant\Migration\Logging\Log\AssociationRequiredMissingLog; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogBuilder; use SwagMigrationAssistant\Migration\Logging\LoggingServiceInterface; use SwagMigrationAssistant\Migration\Mapping\MappingServiceInterface; use SwagMigrationAssistant\Migration\MigrationContextInterface; @@ -34,8 +38,6 @@ abstract class PromotionConverter extends ShopwareConverter */ private array $productUuids; - private string $runId; - /** * @param EntityRepository $salesChannelRepository */ @@ -56,13 +58,9 @@ public function convert(array $data, Context $context, MigrationContextInterface { $this->generateChecksum($data); $this->context = $context; - $this->runId = $migrationContext->getRunUuid(); $connection = $migrationContext->getConnection(); - $this->connectionId = ''; - if ($connection !== null) { - $this->connectionId = $connection->getId(); - } + $this->connectionId = $connection->getId(); $converted = []; $this->mainMapping = $this->mappingService->getOrCreateMapping( @@ -72,7 +70,7 @@ public function convert(array $data, Context $context, MigrationContextInterface $context, $this->checksum ); - $converted['id'] = $this->mainMapping['entityUuid']; + $converted['id'] = $this->mainMapping['entityId']; $converted['active'] = true; $converted['useCodes'] = true; $converted['useIndividualCodes'] = false; @@ -86,12 +84,12 @@ public function convert(array $data, Context $context, MigrationContextInterface $this->setIndividualCodes($data, $converted); } - $this->setSalesChannel($data, $converted); - $this->setProductNumbers($data); + $this->setSalesChannel($data, $converted, $migrationContext); + $this->setProductNumbers($data, $migrationContext); $this->setDiscount($data, $converted); $this->setShippingDiscount($data, $converted); - $this->setCartRule($data, $converted); - $this->setCustomerRule($data, $converted); + $this->setCartRule($data, $converted, $migrationContext); + $this->setCustomerRule($data, $converted, $migrationContext); $this->convertValue($converted, 'name', $data, 'description'); $this->convertValue($converted, 'validFrom', $data, 'valid_from', self::TYPE_DATETIME); @@ -133,7 +131,7 @@ private function setIndividualCodes(array &$data, array &$converted): void ); $newCode = []; - $newCode['id'] = $codeMapping['entityUuid']; + $newCode['id'] = $codeMapping['entityId']; $this->mappingIds[] = $codeMapping['id']; $this->convertValue($newCode, 'code', $code, 'code'); @@ -158,7 +156,7 @@ private function setIndividualCodes(array &$data, array &$converted): void ); if ($customerMapping !== null) { - $newCode['payload']['customerId'] = $customerMapping['entityUuid']; + $newCode['payload']['customerId'] = $customerMapping['entityId']; $this->mappingIds[] = $customerMapping['id']; } } @@ -187,7 +185,7 @@ private function setDiscount(array &$data, array &$converted): void ); $discount = [ - 'id' => $discountMapping['entityUuid'], + 'id' => $discountMapping['entityId'], 'scope' => PromotionDiscountEntity::SCOPE_CART, 'type' => $type, 'value' => (float) $data['value'], @@ -266,20 +264,20 @@ private function getDiscountRule(array $data): ?array $this->mappingIds[] = $orConditionContainerMapping['id']; $rule = [ - 'id' => $ruleMapping['entityUuid'], + 'id' => $ruleMapping['entityId'], 'name' => 'Promotion discount rule: ' . $data['description'], 'priority' => 0, 'conditions' => [ [ - 'id' => $orContainerMapping['entityUuid'], + 'id' => $orContainerMapping['entityId'], 'type' => (new OrRule())->getName(), 'value' => [], ], [ - 'id' => $orConditionContainerMapping['entityUuid'], + 'id' => $orConditionContainerMapping['entityId'], 'type' => (new OrRule())->getName(), - 'parentId' => $orContainerMapping['entityUuid'], + 'parentId' => $orContainerMapping['entityId'], 'value' => [], ], ], @@ -296,9 +294,9 @@ private function getDiscountRule(array $data): ?array $this->mappingIds[] = $conditionMapping['id']; $rule['conditions'][] = [ - 'id' => $conditionMapping['entityUuid'], + 'id' => $conditionMapping['entityId'], 'type' => 'cartLineItem', - 'parentId' => $orConditionContainerMapping['entityUuid'], + 'parentId' => $orConditionContainerMapping['entityId'], 'position' => 1, 'value' => [ 'identifiers' => $this->productUuids, @@ -325,12 +323,12 @@ private function getDiscountRule(array $data): ?array ); $manufacturerRule = [ - 'id' => $manufacturerConditionMapping['entityUuid'], + 'id' => $manufacturerConditionMapping['entityId'], 'type' => 'cartLineItemOfManufacturer', - 'parentId' => $orConditionContainerMapping['entityUuid'], + 'parentId' => $orConditionContainerMapping['entityId'], 'position' => 1, 'value' => [ - 'manufacturerIds' => [$manufacturerMapping['entityUuid']], + 'manufacturerIds' => [$manufacturerMapping['entityId']], 'operator' => '=', ], ]; @@ -350,7 +348,7 @@ private function getDiscountRule(array $data): ?array /** * @param array $data */ - private function setProductNumbers(array &$data): void + private function setProductNumbers(array &$data, MigrationContextInterface $migrationContext): void { if (!isset($data['restrictarticles'])) { return; @@ -370,18 +368,18 @@ private function setProductNumbers(array &$data): void if ($productMapping === null) { $this->loggingService->addLogEntry( - new AssociationRequiredMissingLog( - $this->runId, - DefaultEntities::PRODUCT, - $productNumber, - DefaultEntities::PROMOTION - ) + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withEntityName(PromotionDefinition::ENTITY_NAME) + ->withFieldName('productId') + ->withFieldSourcePath('restrictarticles') + ->withSourceData($data) + ->build(AssociationRequiredMissingLog::class) ); continue; } - $this->productUuids[] = (string) $productMapping['entityUuid']; + $this->productUuids[] = (string) $productMapping['entityId']; $this->mappingIds[] = $productMapping['id']; unset($data['restrictarticles']); } @@ -392,7 +390,7 @@ private function setProductNumbers(array &$data): void * @param array $data * @param array $converted */ - private function setCartRule(array &$data, array &$converted): void + private function setCartRule(array &$data, array &$converted, MigrationContextInterface $migrationContext): void { if (empty($this->productUuids) && !isset($data['bindtosupplier']) && !isset($data['minimumcharge'])) { return; @@ -431,20 +429,20 @@ private function setCartRule(array &$data, array &$converted): void $this->mappingIds[] = $andContainerMapping['id']; $rule = [ - 'id' => $ruleMapping['entityUuid'], + 'id' => $ruleMapping['entityId'], 'name' => 'Promotion cart rule: ' . $data['description'], 'priority' => 0, 'conditions' => [ [ - 'id' => $orContainerMapping['entityUuid'], + 'id' => $orContainerMapping['entityId'], 'type' => (new OrRule())->getName(), 'value' => [], ], [ - 'id' => $andContainerMapping['entityUuid'], + 'id' => $andContainerMapping['entityId'], 'type' => (new AndRule())->getName(), - 'parentId' => $orContainerMapping['entityUuid'], + 'parentId' => $orContainerMapping['entityId'], 'value' => [], ], ], @@ -461,9 +459,9 @@ private function setCartRule(array &$data, array &$converted): void $this->mappingIds[] = $conditionMapping['id']; $rule['conditions'][] = [ - 'id' => $conditionMapping['entityUuid'], + 'id' => $conditionMapping['entityId'], 'type' => 'cartLineItem', - 'parentId' => $andContainerMapping['entityUuid'], + 'parentId' => $andContainerMapping['entityId'], 'position' => 1, 'value' => [ 'identifiers' => $this->productUuids, @@ -490,12 +488,12 @@ private function setCartRule(array &$data, array &$converted): void ); $manufacturerRule = [ - 'id' => $manufacturerConditionMapping['entityUuid'], + 'id' => $manufacturerConditionMapping['entityId'], 'type' => 'cartLineItemOfManufacturer', - 'parentId' => $andContainerMapping['entityUuid'], + 'parentId' => $andContainerMapping['entityId'], 'position' => 1, 'value' => [ - 'manufacturerIds' => [$manufacturerMapping['entityUuid']], + 'manufacturerIds' => [$manufacturerMapping['entityId']], 'operator' => '=', ], ]; @@ -505,12 +503,12 @@ private function setCartRule(array &$data, array &$converted): void $oneRuleAdded = true; } else { $this->loggingService->addLogEntry( - new AssociationRequiredMissingLog( - $this->runId, - DefaultEntities::PRODUCT_MANUFACTURER, - $data['bindtosupplier'], - DefaultEntities::PROMOTION_DISCOUNT - ) + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withEntityName(PromotionCartRuleDefinition::ENTITY_NAME) + ->withFieldName('rule.value.manufacturerId') + ->withFieldSourcePath('bindtosupplier') + ->withSourceData($data) + ->build(AssociationRequiredMissingLog::class) ); } } @@ -524,9 +522,9 @@ private function setCartRule(array &$data, array &$converted): void ); $cartGoodsPriceRule = [ - 'id' => $cartGoodsPriceConditionMapping['entityUuid'], + 'id' => $cartGoodsPriceConditionMapping['entityId'], 'type' => 'cartGoodsPrice', - 'parentId' => $andContainerMapping['entityUuid'], + 'parentId' => $andContainerMapping['entityId'], 'position' => 1, 'value' => [ 'amount' => (float) $data['minimumcharge'], @@ -548,7 +546,7 @@ private function setCartRule(array &$data, array &$converted): void * @param array $data * @param array $converted */ - private function setSalesChannel(array &$data, array &$converted): void + private function setSalesChannel(array &$data, array &$converted, MigrationContextInterface $migrationContext): void { if (isset($data['subshopID'])) { $salesChannelMapping = $this->mappingService->getMapping( @@ -560,12 +558,13 @@ private function setSalesChannel(array &$data, array &$converted): void if ($salesChannelMapping === null) { $this->loggingService->addLogEntry( - new AssociationRequiredMissingLog( - $this->runId, - DefaultEntities::SALES_CHANNEL, - $data['subshopID'], - DefaultEntities::PROMOTION - ) + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withEntityName(PromotionDefinition::ENTITY_NAME) + ->withFieldName('salesChannelId') + ->withFieldSourcePath('subshopID') + ->withSourceData($data) + ->withConvertedData($converted) + ->build(AssociationRequiredMissingLog::class) ); return; @@ -581,8 +580,8 @@ private function setSalesChannel(array &$data, array &$converted): void $this->mappingIds[] = $salesChannelRelationMapping['id']; $converted['salesChannels'][] = [ - 'id' => $salesChannelRelationMapping['entityUuid'], - 'salesChannelId' => $salesChannelMapping['entityUuid'], + 'id' => $salesChannelRelationMapping['entityId'], + 'salesChannelId' => $salesChannelMapping['entityId'], 'priority' => 0, ]; unset($data['subshopID']); @@ -605,7 +604,7 @@ private function setSalesChannel(array &$data, array &$converted): void $this->mappingIds[] = $salesChannelRelationMapping['id']; $converted['salesChannels'][] = [ - 'id' => $salesChannelRelationMapping['entityUuid'], + 'id' => $salesChannelRelationMapping['entityId'], 'salesChannelId' => $salesChannelId, 'priority' => $priority++, ]; @@ -617,7 +616,7 @@ private function setSalesChannel(array &$data, array &$converted): void * @param array $data * @param array $converted */ - private function setCustomerRule(array &$data, array &$converted): void + private function setCustomerRule(array &$data, array &$converted, MigrationContextInterface $migrationContext): void { if (!isset($data['customergroup'])) { return; @@ -631,12 +630,15 @@ private function setCustomerRule(array &$data, array &$converted): void ); if ($customerGroupMapping === null) { - $this->loggingService->addLogEntry(new AssociationRequiredMissingLog( - $this->runId, - DefaultEntities::CUSTOMER_GROUP, - $data['customergroup'], - DefaultEntities::PROMOTION - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withEntityName(PromotionPersonaRuleDefinition::ENTITY_NAME) + ->withFieldName('rule.value.customerGroupId') + ->withFieldSourcePath('customergroup') + ->withSourceData($data) + ->withConvertedData($converted) + ->build(AssociationRequiredMissingLog::class) + ); return; } @@ -683,30 +685,30 @@ private function setCustomerRule(array &$data, array &$converted): void $this->mappingIds[] = $conditionMapping['id']; $rule = [ - 'id' => $ruleMapping['entityUuid'], + 'id' => $ruleMapping['entityId'], 'name' => 'Promotion customer rule: ' . $data['description'], 'priority' => 0, 'conditions' => [ [ - 'id' => $orContainerMapping['entityUuid'], + 'id' => $orContainerMapping['entityId'], 'type' => (new OrRule())->getName(), 'value' => [], ], [ - 'id' => $andContainerMapping['entityUuid'], + 'id' => $andContainerMapping['entityId'], 'type' => (new AndRule())->getName(), - 'parentId' => $orContainerMapping['entityUuid'], + 'parentId' => $orContainerMapping['entityId'], 'value' => [], ], [ - 'id' => $conditionMapping['entityUuid'], + 'id' => $conditionMapping['entityId'], 'type' => 'customerCustomerGroup', - 'parentId' => $andContainerMapping['entityUuid'], + 'parentId' => $andContainerMapping['entityId'], 'position' => 1, 'value' => [ 'customerGroupIds' => [ - $customerGroupMapping['entityUuid'], + $customerGroupMapping['entityId'], ], 'operator' => '=', ], @@ -736,7 +738,7 @@ private function setShippingDiscount(array $data, array &$converted): void ); $deliveryDiscount = [ - 'id' => $deliveryDiscountMapping['entityUuid'], + 'id' => $deliveryDiscountMapping['entityId'], 'scope' => PromotionDiscountEntity::SCOPE_DELIVERY, 'type' => PromotionDiscountEntity::TYPE_PERCENTAGE, 'value' => 100, diff --git a/src/Profile/Shopware/Converter/PropertyGroupOptionConverter.php b/src/Profile/Shopware/Converter/PropertyGroupOptionConverter.php index 4b07125d6..9dd355a16 100644 --- a/src/Profile/Shopware/Converter/PropertyGroupOptionConverter.php +++ b/src/Profile/Shopware/Converter/PropertyGroupOptionConverter.php @@ -7,12 +7,14 @@ namespace SwagMigrationAssistant\Profile\Shopware\Converter; +use Shopware\Core\Content\Property\PropertyGroupDefinition; use Shopware\Core\Framework\Context; use Shopware\Core\Framework\Log\Package; +use Shopware\Core\Framework\Util\Hasher; use SwagMigrationAssistant\Migration\Converter\ConvertStruct; use SwagMigrationAssistant\Migration\DataSelection\DefaultEntities; -use SwagMigrationAssistant\Migration\Logging\Log\CannotConvertChildEntity; -use SwagMigrationAssistant\Migration\Logging\Log\EmptyNecessaryFieldRunLog; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogBuilder; +use SwagMigrationAssistant\Migration\Logging\Log\CannotConvertChildEntityLog; use SwagMigrationAssistant\Migration\Logging\LoggingServiceInterface; use SwagMigrationAssistant\Migration\Mapping\Lookup\LanguageLookup; use SwagMigrationAssistant\Migration\Mapping\MappingServiceInterface; @@ -47,7 +49,7 @@ public function getSourceIdentifier(array $data): string $group = $data['group']['name']; } - return \hash('md5', \mb_strtolower($data['name'] . '_' . $group . '_' . $data['type'])); + return Hasher::hash(\mb_strtolower($data['name'] . '_' . $group . '_' . $data['type']), 'md5'); } public function getMediaUuids(array $converted): ?array @@ -72,45 +74,31 @@ public function convert(array $data, Context $context, MigrationContextInterface $this->runId = $migrationContext->getRunUuid(); $connection = $migrationContext->getConnection(); - $this->connectionId = ''; - if ($connection !== null) { - $this->connectionId = $connection->getId(); - } - - if (!isset($data['group']['name'])) { - $this->loggingService->addLogEntry(new EmptyNecessaryFieldRunLog( - $this->runId, + $this->connectionId = $connection->getId(); + $converted = []; + if (isset($data['group']['name'])) { + $mapping = $this->mappingService->getOrCreateMapping( + $this->connectionId, DefaultEntities::PROPERTY_GROUP_OPTION, - $data['id'], - 'group' - )); - - return new ConvertStruct(null, $data); + Hasher::hash(\mb_strtolower($data['name'] . '_' . $data['group']['name']), 'md5'), + $context + ); + $this->mappingIds[] = $mapping['id']; + + $propertyGroupMapping = $this->mappingService->getOrCreateMapping( + $this->connectionId, + DefaultEntities::PROPERTY_GROUP, + Hasher::hash(\mb_strtolower($data['group']['name']), 'md5'), + $context + ); + $this->mappingIds[] = $propertyGroupMapping['id']; + + $converted['id'] = $mapping['entityId']; + $converted['group'] = [ + 'id' => $propertyGroupMapping['entityId'], + ]; } - $mapping = $this->mappingService->getOrCreateMapping( - $this->connectionId, - DefaultEntities::PROPERTY_GROUP_OPTION, - \hash('md5', \mb_strtolower($data['name'] . '_' . $data['group']['name'])), - $context - ); - $this->mappingIds[] = $mapping['id']; - - $propertyGroupMapping = $this->mappingService->getOrCreateMapping( - $this->connectionId, - DefaultEntities::PROPERTY_GROUP, - \hash('md5', \mb_strtolower($data['group']['name'])), - $context - ); - $this->mappingIds[] = $propertyGroupMapping['id']; - - $converted = [ - 'id' => $mapping['entityUuid'], - 'group' => [ - 'id' => $propertyGroupMapping['entityUuid'], - ], - ]; - $this->createAndDeleteNecessaryMappings($data, $converted); if (isset($data['media'])) { @@ -132,12 +120,14 @@ public function convert(array $data, Context $context, MigrationContextInterface protected function setMedia(array &$converted, array $data): void { if (!isset($data['media']['id'])) { - $this->loggingService->addLogEntry(new CannotConvertChildEntity( - $this->runId, - 'property_group_option_media', - DefaultEntities::PROPERTY_GROUP_OPTION, - $data['id'] - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(PropertyGroupDefinition::ENTITY_NAME) + ->withFieldName('media.id') + ->withFieldSourcePath('media.id') + ->withSourceData($data) + ->build(CannotConvertChildEntityLog::class) + ); return; } @@ -149,7 +139,7 @@ protected function setMedia(array &$converted, array $data): void $data['media']['id'], $this->context ); - $newMedia['id'] = $mapping['entityUuid']; + $newMedia['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; if (empty($data['media']['name'])) { @@ -179,7 +169,7 @@ protected function setMedia(array &$converted, array $data): void ); if ($albumMapping !== null) { - $newMedia['mediaFolderId'] = $albumMapping['entityUuid']; + $newMedia['mediaFolderId'] = $albumMapping['entityId']; $this->mappingIds[] = $albumMapping['id']; } @@ -213,7 +203,7 @@ protected function setMediaTranslation(array &$media, array $data): void $data['media']['id'] . ':' . $this->locale, $this->context ); - $localeTranslation['id'] = $mapping['entityUuid']; + $localeTranslation['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $languageUuid = $this->languageLookup->get($this->locale, $this->context); @@ -254,7 +244,7 @@ protected function createAndDeleteNecessaryMappings(array $data, array $converte $this->mainMapping = $this->mappingService->getOrCreateMapping( $this->connectionId, DefaultEntities::PROPERTY_GROUP_OPTION, - \hash('md5', \mb_strtolower($data['name'] . '_' . $data['group']['name'] . '_' . $data['type'])), + Hasher::hash(\mb_strtolower($data['name'] . '_' . $data['group']['name'] . '_' . $data['type']), 'md5'), $this->context, $this->checksum ); @@ -262,7 +252,7 @@ protected function createAndDeleteNecessaryMappings(array $data, array $converte $mapping = $this->mappingService->getOrCreateMapping( $this->connectionId, DefaultEntities::PROPERTY_GROUP_OPTION, - \hash('md5', \mb_strtolower($data['group']['name'] . '_' . $data['type'])), + Hasher::hash(\mb_strtolower($data['group']['name'] . '_' . $data['type']), 'md5'), $this->context ); $this->mappingIds[] = $mapping['id']; diff --git a/src/Profile/Shopware/Converter/SalesChannelConverter.php b/src/Profile/Shopware/Converter/SalesChannelConverter.php index 6494fa260..037c89f3e 100644 --- a/src/Profile/Shopware/Converter/SalesChannelConverter.php +++ b/src/Profile/Shopware/Converter/SalesChannelConverter.php @@ -20,15 +20,15 @@ use Shopware\Core\Framework\Log\Package; use Shopware\Core\System\Country\CountryCollection; use Shopware\Core\System\SalesChannel\SalesChannelCollection; +use Shopware\Core\System\SalesChannel\SalesChannelDefinition; use SwagMigrationAssistant\Migration\Converter\ConvertStruct; use SwagMigrationAssistant\Migration\DataSelection\DefaultEntities; -use SwagMigrationAssistant\Migration\Logging\Log\AssociationRequiredMissingLog; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogBuilder; use SwagMigrationAssistant\Migration\Logging\LoggingServiceInterface; use SwagMigrationAssistant\Migration\Mapping\Lookup\CurrencyLookup; use SwagMigrationAssistant\Migration\Mapping\Lookup\LanguageLookup; use SwagMigrationAssistant\Migration\Mapping\MappingServiceInterface; use SwagMigrationAssistant\Migration\MigrationContextInterface; -use SwagMigrationAssistant\Profile\Shopware\DataSelection\DataSet\SalesChannelDataSet; use SwagMigrationAssistant\Profile\Shopware\Logging\Log\DeactivatedPackLanguageLog; use SwagMigrationAssistant\Profile\Shopware\Premapping\PaymentMethodReader; @@ -72,10 +72,7 @@ public function convert(array $data, Context $context, MigrationContextInterface $this->oldIdentifier = $data['id']; $connection = $migrationContext->getConnection(); - $this->connectionId = ''; - if ($connection !== null) { - $this->connectionId = $connection->getId(); - } + $this->connectionId = $connection->getId(); $converted = []; $this->mainMapping = $this->mappingService->getOrCreateMapping( @@ -85,7 +82,7 @@ public function convert(array $data, Context $context, MigrationContextInterface $context, $this->checksum ); - $converted['id'] = (string) $this->mainMapping['entityUuid']; + $converted['id'] = (string) $this->mainMapping['entityId']; if (isset($data['children']) && \count($data['children']) > 0) { $this->setRelationMappings($data['children']); @@ -98,40 +95,21 @@ public function convert(array $data, Context $context, MigrationContextInterface $context ); - if ($customerGroupMapping === null) { - $this->loggingService->addLogEntry( - new AssociationRequiredMissingLog( - $migrationContext->getRunUuid(), - DefaultEntities::CUSTOMER_GROUP, - $data['customer_group_id'], - DefaultEntities::SALES_CHANNEL - ) - ); - - return new ConvertStruct(null, $data); + if ($customerGroupMapping !== null) { + $this->mappingIds[] = $customerGroupMapping['id']; + $converted['customerGroupId'] = $customerGroupMapping['entityId']; } - $customerGroupUuid = $customerGroupMapping['entityUuid']; - $this->mappingIds[] = $customerGroupMapping['id']; - $converted['customerGroupId'] = $customerGroupUuid; $languageUuid = $this->languageLookup->get($data['locale'], $context); - if ($languageUuid === null) { - $this->loggingService->addLogEntry( - new AssociationRequiredMissingLog( - $migrationContext->getRunUuid(), - DefaultEntities::LANGUAGE, - $data['locale'], - DefaultEntities::SALES_CHANNEL - ) - ); - - return new ConvertStruct(null, $data); + if ($languageUuid !== null) { + $converted['languageId'] = $languageUuid; + $converted['languages'] = $this->getSalesChannelLanguages($languageUuid, $data, $context); } - $converted['languageId'] = $languageUuid; - $converted['languages'] = $this->getSalesChannelLanguages($languageUuid, $data, $context); + if (isset($converted['languages'])) { + $this->filterExistingLanguageSalesChannelRelation($converted['id'], $converted['languages']); + } - $this->filterExistingLanguageSalesChannelRelation($converted['id'], $converted['languages']); $this->filterDisabledPackLanguages($converted); if (empty($converted['languages'])) { @@ -139,26 +117,15 @@ public function convert(array $data, Context $context, MigrationContextInterface } $currencyUuid = $this->currencyLookup->get($data['currency'], $context); - if ($currencyUuid === null) { - $this->loggingService->addLogEntry( - new AssociationRequiredMissingLog( - $migrationContext->getRunUuid(), - DefaultEntities::CURRENCY, - $data['currency'], - DefaultEntities::SALES_CHANNEL - ) - ); - - return new ConvertStruct(null, $data); + if ($currencyUuid !== null) { + $converted['currencyId'] = $currencyUuid; + $converted['currencies'] = [ + [ + 'id' => $currencyUuid, + ], + ]; } - $converted['currencyId'] = $currencyUuid; - $converted['currencies'] = [ - [ - 'id' => $currencyUuid, - ], - ]; - $categoryMapping = $this->mappingService->getMapping( $this->connectionId, DefaultEntities::CATEGORY, @@ -166,21 +133,10 @@ public function convert(array $data, Context $context, MigrationContextInterface $context ); - if ($categoryMapping === null) { - $this->loggingService->addLogEntry( - new AssociationRequiredMissingLog( - $migrationContext->getRunUuid(), - DefaultEntities::CATEGORY, - $data['category_id'], - DefaultEntities::SALES_CHANNEL - ) - ); - - return new ConvertStruct(null, $data); + if ($categoryMapping !== null) { + $this->mappingIds[] = $categoryMapping['id']; + $converted['navigationCategoryId'] = $categoryMapping['entityId']; } - $categoryUuid = $categoryMapping['entityUuid']; - $this->mappingIds[] = $categoryMapping['id']; - $converted['navigationCategoryId'] = $categoryUuid; $countryUuid = $this->getFirstActiveCountryId(); $converted['countryId'] = $countryUuid; @@ -272,7 +228,7 @@ protected function setSalesChannelTranslation(array &$salesChannel, array $data) $data['id'] . ':' . $this->mainLocale, $this->context ); - $localeTranslation['id'] = $mapping['entityUuid']; + $localeTranslation['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $languageUuid = $this->languageLookup->get($this->mainLocale, $this->context); @@ -299,7 +255,7 @@ protected function getFirstActiveShippingMethodId(): string ); if ($mapping !== null) { - $id = (string) $mapping['entityUuid']; + $id = (string) $mapping['entityId']; } } @@ -324,7 +280,7 @@ protected function getFirstActivePaymentMethodId(): string ); if ($mapping !== null) { - $id = (string) $mapping['entityUuid']; + $id = (string) $mapping['entityId']; } } @@ -392,7 +348,10 @@ protected function filterDisabledPackLanguages(array &$converted): void } $this->loggingService->addLogEntry( - new DeactivatedPackLanguageLog($this->migrationContext->getRunUuid(), SalesChannelDataSet::getEntity(), $this->oldIdentifier, $packLanguageId) + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(SalesChannelDefinition::ENTITY_NAME) + ->withFieldName('languageId') + ->build(DeactivatedPackLanguageLog::class) ); } } @@ -431,7 +390,7 @@ protected function getSalesChannelLanguages(string $languageUuid, array $data, C */ private function setRelationMappings(array $children): void { - if (!isset($this->mainMapping['entityUuid'])) { + if (!isset($this->mainMapping['entityId'])) { return; } @@ -443,7 +402,7 @@ private function setRelationMappings(array $children): void $this->context, null, null, - $this->mainMapping['entityUuid'] + $this->mainMapping['entityId'] ); $this->mappingIds[] = $mapping['id']; } diff --git a/src/Profile/Shopware/Converter/SeoUrlConverter.php b/src/Profile/Shopware/Converter/SeoUrlConverter.php index 175e84d51..3c3ffde91 100644 --- a/src/Profile/Shopware/Converter/SeoUrlConverter.php +++ b/src/Profile/Shopware/Converter/SeoUrlConverter.php @@ -11,12 +11,10 @@ use Shopware\Core\Framework\Log\Package; use SwagMigrationAssistant\Migration\Converter\ConvertStruct; use SwagMigrationAssistant\Migration\DataSelection\DefaultEntities; -use SwagMigrationAssistant\Migration\Logging\Log\AssociationRequiredMissingLog; use SwagMigrationAssistant\Migration\Logging\LoggingServiceInterface; use SwagMigrationAssistant\Migration\Mapping\Lookup\LanguageLookup; use SwagMigrationAssistant\Migration\Mapping\MappingServiceInterface; use SwagMigrationAssistant\Migration\MigrationContextInterface; -use SwagMigrationAssistant\Profile\Shopware\Logging\Log\UnsupportedSeoUrlType; #[Package('fundamentals@after-sales')] abstract class SeoUrlConverter extends ShopwareConverter @@ -40,13 +38,9 @@ public function __construct( public function convert(array $data, Context $context, MigrationContextInterface $migrationContext): ConvertStruct { $this->generateChecksum($data); - $originalData = $data; $connection = $migrationContext->getConnection(); - $this->connectionId = ''; - if ($connection !== null) { - $this->connectionId = $connection->getId(); - } + $this->connectionId = $connection->getId(); $converted = []; $this->mainMapping = $this->mappingService->getOrCreateMapping( @@ -56,7 +50,7 @@ public function convert(array $data, Context $context, MigrationContextInterface $context, $this->checksum ); - $converted['id'] = $this->mainMapping['entityUuid']; + $converted['id'] = $this->mainMapping['entityId']; unset($data['id']); $mapping = $this->mappingService->getMapping( @@ -66,37 +60,17 @@ public function convert(array $data, Context $context, MigrationContextInterface $context ); - if ($mapping === null) { - $this->loggingService->addLogEntry( - new AssociationRequiredMissingLog( - $migrationContext->getRunUuid(), - DefaultEntities::SALES_CHANNEL, - $data['subshopID'], - DefaultEntities::SEO_URL - ) - ); - - return new ConvertStruct(null, $originalData); + if ($mapping !== null) { + $converted['salesChannelId'] = $mapping['entityId']; + $this->mappingIds[] = $mapping['id']; + unset($data['subshopID']); } - $converted['salesChannelId'] = $mapping['entityUuid']; - $this->mappingIds[] = $mapping['id']; - unset($data['subshopID']); $converted['languageId'] = $this->languageLookup->get($data['_locale'], $context); - if ($converted['languageId'] === null) { - $this->loggingService->addLogEntry( - new AssociationRequiredMissingLog( - $migrationContext->getRunUuid(), - DefaultEntities::LANGUAGE, - $data['_locale'], - DefaultEntities::SEO_URL - ) - ); - - return new ConvertStruct(null, $originalData); + if ($converted['languageId'] !== null) { + $this->mappingIds[] = $converted['languageId']; + unset($data['_locale']); } - $this->mappingIds[] = $converted['languageId']; - unset($data['_locale']); if ($data['type'] === self::TYPE_PRODUCT && isset($data['typeId'])) { $mapping = $this->mappingService->getMapping( @@ -113,25 +87,14 @@ public function convert(array $data, Context $context, MigrationContextInterface $data['typeId'], $context ); - - if ($mapping === null) { - $this->loggingService->addLogEntry( - new AssociationRequiredMissingLog( - $migrationContext->getRunUuid(), - DefaultEntities::PRODUCT, - $data['typeId'], - DefaultEntities::SEO_URL - ) - ); - - return new ConvertStruct(null, $originalData); - } } - $converted['foreignKey'] = $mapping['entityUuid']; - $converted['routeName'] = self::ROUTE_NAME_PRODUCT; - $converted['pathInfo'] = '/detail/' . $mapping['entityUuid']; - $this->mappingIds[] = $mapping['id']; + if ($mapping !== null) { + $converted['foreignKey'] = $mapping['entityId']; + $converted['routeName'] = self::ROUTE_NAME_PRODUCT; + $converted['pathInfo'] = '/detail/' . $mapping['entityId']; + $this->mappingIds[] = $mapping['id']; + } } elseif ($data['type'] === self::TYPE_CATEGORY && isset($data['typeId'])) { $mapping = $this->mappingService->getMapping( $this->connectionId, @@ -140,33 +103,12 @@ public function convert(array $data, Context $context, MigrationContextInterface $context ); - if ($mapping === null) { - $this->loggingService->addLogEntry( - new AssociationRequiredMissingLog( - $migrationContext->getRunUuid(), - DefaultEntities::CATEGORY, - $data['typeId'], - DefaultEntities::SEO_URL - ) - ); - - return new ConvertStruct(null, $originalData); + if ($mapping !== null) { + $converted['foreignKey'] = $mapping['entityId']; + $converted['routeName'] = self::ROUTE_NAME_NAVIGATION; + $converted['pathInfo'] = '/navigation/' . $mapping['entityId']; + $this->mappingIds[] = $mapping['id']; } - $converted['foreignKey'] = $mapping['entityUuid']; - $converted['routeName'] = self::ROUTE_NAME_NAVIGATION; - $converted['pathInfo'] = '/navigation/' . $mapping['entityUuid']; - $this->mappingIds[] = $mapping['id']; - } else { - $this->loggingService->addLogEntry( - new UnsupportedSeoUrlType( - $migrationContext->getRunUuid(), - $data['type'], - DefaultEntities::SEO_URL, - $originalData['id'] - ) - ); - - return new ConvertStruct(null, $originalData); } unset($data['type'], $data['typeId']); diff --git a/src/Profile/Shopware/Converter/ShippingMethodConverter.php b/src/Profile/Shopware/Converter/ShippingMethodConverter.php index 12954c92a..1c9c69d7e 100644 --- a/src/Profile/Shopware/Converter/ShippingMethodConverter.php +++ b/src/Profile/Shopware/Converter/ShippingMethodConverter.php @@ -7,19 +7,23 @@ namespace SwagMigrationAssistant\Profile\Shopware\Converter; +use Shopware\Core\Checkout\Shipping\Aggregate\ShippingMethodPrice\ShippingMethodPriceDefinition; +use Shopware\Core\Checkout\Shipping\ShippingMethodDefinition; use Shopware\Core\Framework\Context; use Shopware\Core\Framework\Log\Package; use Shopware\Core\Framework\Rule\Container\AndRule; use Shopware\Core\Framework\Rule\Container\OrRule; +use Shopware\Core\Framework\Util\Hasher; use SwagMigrationAssistant\Migration\Converter\ConvertStruct; use SwagMigrationAssistant\Migration\DataSelection\DefaultEntities; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogBuilder; use SwagMigrationAssistant\Migration\Logging\Log\EmptyNecessaryFieldRunLog; use SwagMigrationAssistant\Migration\Logging\LoggingServiceInterface; use SwagMigrationAssistant\Migration\Mapping\Lookup\CountryLookup; use SwagMigrationAssistant\Migration\Mapping\Lookup\LanguageLookup; use SwagMigrationAssistant\Migration\Mapping\MappingServiceInterface; use SwagMigrationAssistant\Migration\MigrationContextInterface; -use SwagMigrationAssistant\Profile\Shopware\Logging\Log\UnsupportedShippingCalculationType; +use SwagMigrationAssistant\Profile\Shopware\Logging\Log\UnsupportedShippingCalculationTypeLog; use SwagMigrationAssistant\Profile\Shopware\Logging\Log\UnsupportedShippingPriceLog; use SwagMigrationAssistant\Profile\Shopware\Premapping\DefaultShippingAvailabilityRuleReader; use SwagMigrationAssistant\Profile\Shopware\Premapping\DeliveryTimeReader; @@ -70,13 +74,6 @@ abstract class ShippingMethodConverter extends ShopwareConverter protected string $mainLocale; - /** - * @var array - */ - protected array $requiredDataFields = [ - 'deliveryTimeId' => 'delivery_time', - ]; - public function __construct( MappingServiceInterface $mappingService, LoggingServiceInterface $loggingService, @@ -88,30 +85,20 @@ public function __construct( public function convert(array $data, Context $context, MigrationContextInterface $migrationContext): ConvertStruct { - if (empty($data['id'])) { - $this->loggingService->addLogEntry(new EmptyNecessaryFieldRunLog( - $this->runId, - DefaultEntities::SHIPPING_METHOD, - '', - 'id', - )); - - return new ConvertStruct(null, $data); - } + $connection = $migrationContext->getConnection(); + $this->connectionId = $connection->getId(); $this->generateChecksum($data); $this->context = $context; $this->runId = $migrationContext->getRunUuid(); - $this->oldShippingMethod = $data['id']; - $this->mainLocale = $data['_locale']; + $converted = []; - $connection = $migrationContext->getConnection(); - $this->connectionId = ''; - if ($connection !== null) { - $this->connectionId = $connection->getId(); + if (!empty($data['id'])) { + $this->oldShippingMethod = $data['id']; } - $converted = []; + $this->mainLocale = $data['_locale']; + $this->mainMapping = $this->mappingService->getOrCreateMapping( $this->connectionId, DefaultEntities::SHIPPING_METHOD, @@ -120,7 +107,7 @@ public function convert(array $data, Context $context, MigrationContextInterface $this->checksum ); - $converted['id'] = $this->mainMapping['entityUuid']; + $converted['id'] = $this->mainMapping['entityId']; $defaultDeliveryTimeMapping = $this->mappingService->getMapping( $this->connectionId, @@ -130,7 +117,7 @@ public function convert(array $data, Context $context, MigrationContextInterface ); if ($defaultDeliveryTimeMapping !== null) { - $converted['deliveryTimeId'] = $defaultDeliveryTimeMapping['entityUuid']; + $converted['deliveryTimeId'] = $defaultDeliveryTimeMapping['entityId']; $this->mappingIds[] = $defaultDeliveryTimeMapping['id']; } @@ -141,24 +128,10 @@ public function convert(array $data, Context $context, MigrationContextInterface $this->context ); if ($defaultAvailabilityRuleUuid !== null) { - $converted['availabilityRuleId'] = $defaultAvailabilityRuleUuid['entityUuid']; + $converted['availabilityRuleId'] = $defaultAvailabilityRuleUuid['entityId']; $this->mappingIds[] = $defaultAvailabilityRuleUuid['id']; } - $fields = $this->checkForEmptyRequiredConvertedFields($converted, $this->requiredDataFields); - if (!empty($fields)) { - foreach ($fields as $field) { - $this->loggingService->addLogEntry(new EmptyNecessaryFieldRunLog( - $this->runId, - DefaultEntities::SHIPPING_METHOD, - $this->oldShippingMethod, - $field - )); - } - - return new ConvertStruct(null, $data); - } - $converted['technicalName'] = 'migrated_' . $data['id']; $this->addShippingMethodTranslation($converted, $data); @@ -184,15 +157,18 @@ public function convert(array $data, Context $context, MigrationContextInterface if (!isset($data['calculation']) || !\array_key_exists($data['calculation'], self::CALCULATION_TYPE_MAPPING) ) { - $this->loggingService->addLogEntry(new UnsupportedShippingCalculationType( - $this->runId, - DefaultEntities::SHIPPING_METHOD, - $this->oldShippingMethod, - $data['calculation'] - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withEntityName(ShippingMethodDefinition::ENTITY_NAME) + ->withFieldName('prices') + ->withFieldSourcePath('calculation') + ->withSourceData($data) + ->withConvertedData($converted) + ->build(UnsupportedShippingCalculationTypeLog::class) + ); } else { $calculationType = self::CALCULATION_TYPE_MAPPING[$data['calculation']]; - $converted['prices'] = $this->getShippingCosts($data, $calculationType, $priceRule); + $converted['prices'] = $this->getShippingCosts($migrationContext, $data, $calculationType, $priceRule); } } @@ -240,17 +216,6 @@ public function convert(array $data, Context $context, MigrationContextInterface } $this->updateMainMapping($migrationContext, $context); - if (!\is_array($this->mainMapping) || !\array_key_exists('id', $this->mainMapping)) { - $this->loggingService->addLogEntry(new EmptyNecessaryFieldRunLog( - $this->runId, - DefaultEntities::SHIPPING_METHOD, - $this->oldShippingMethod, - 'id', - )); - - return new ConvertStruct(null, $data); - } - return new ConvertStruct($converted, $returnData, $this->mainMapping['id'] ?? null); } @@ -283,7 +248,7 @@ protected function addShippingMethodTranslation(array &$shippingMethod, array $d $data['id'] . ':' . $this->mainLocale, $this->context ); - $localeTranslation['id'] = $mapping['entityUuid']; + $localeTranslation['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $languageUuid = $this->languageLookup->get($this->mainLocale, $this->context); @@ -323,7 +288,7 @@ protected function getCustomerGroupCalculationRule(array $data): array 'customerGroupRule_' . $customerGroupId, $this->context ); - $priceRuleUuid = $mapping['entityUuid']; + $priceRuleUuid = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $mapping = $this->mappingService->getOrCreateMapping( @@ -332,7 +297,7 @@ protected function getCustomerGroupCalculationRule(array $data): array 'customerGroupRule_orContainer_' . $customerGroupId, $this->context ); - $orContainerUuid = $mapping['entityUuid']; + $orContainerUuid = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $mapping = $this->mappingService->getOrCreateMapping( @@ -341,7 +306,7 @@ protected function getCustomerGroupCalculationRule(array $data): array 'customerGroupRule_andContainer_' . $customerGroupId, $this->context ); - $andContainerUuid = $mapping['entityUuid']; + $andContainerUuid = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $mapping = $this->mappingService->getOrCreateMapping( @@ -350,7 +315,7 @@ protected function getCustomerGroupCalculationRule(array $data): array 'customerGroupRule_condition_' . $customerGroupId, $this->context ); - $conditionUuid = $mapping['entityUuid']; + $conditionUuid = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $rule = [ @@ -381,7 +346,7 @@ protected function getCustomerGroupCalculationRule(array $data): array 'position' => 1, 'value' => [ 'customerGroupIds' => [ - $customerGroupMapping['entityUuid'], + $customerGroupMapping['entityId'], ], 'operator' => '=', ], @@ -411,7 +376,7 @@ protected function getSalesChannelCalculationRule(array $data): array return []; } - $salesChannelUuid = $salesChannelMapping['entityUuid']; + $salesChannelUuid = $salesChannelMapping['entityId']; $this->mappingIds[] = $salesChannelMapping['id']; $salesChannelName = $shopId; if (isset($data['shop']['name'])) { @@ -424,7 +389,7 @@ protected function getSalesChannelCalculationRule(array $data): array 'salesChannelRule_' . $shopId, $this->context ); - $priceRuleUuid = (string) $mapping['entityUuid']; + $priceRuleUuid = (string) $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $mapping = $this->mappingService->getOrCreateMapping( @@ -433,7 +398,7 @@ protected function getSalesChannelCalculationRule(array $data): array 'salesChannelRule_orContainer_' . $shopId, $this->context ); - $orContainerUuid = (string) $mapping['entityUuid']; + $orContainerUuid = (string) $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $mapping = $this->mappingService->getOrCreateMapping( @@ -442,7 +407,7 @@ protected function getSalesChannelCalculationRule(array $data): array 'salesChannelRule_andContainer_' . $shopId, $this->context ); - $andContainerUuid = (string) $mapping['entityUuid']; + $andContainerUuid = (string) $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $mapping = $this->mappingService->getOrCreateMapping( @@ -451,7 +416,7 @@ protected function getSalesChannelCalculationRule(array $data): array 'salesChannelRule_condition_' . $shopId, $this->context ); - $conditionUuid = (string) $mapping['entityUuid']; + $conditionUuid = (string) $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $rule = [ @@ -511,7 +476,7 @@ protected function getSalesChannelAndCustomerGroupCalculationRule(array $data): if ($salesChannelMapping === null) { return []; } - $salesChannelUuid = $salesChannelMapping['entityUuid']; + $salesChannelUuid = $salesChannelMapping['entityId']; $this->mappingIds[] = $salesChannelMapping['id']; $customerGroupId = $data['customergroupID']; @@ -526,7 +491,7 @@ protected function getSalesChannelAndCustomerGroupCalculationRule(array $data): return []; } - $customerGroupUuid = $customerGroupMapping['entityUuid']; + $customerGroupUuid = $customerGroupMapping['entityId']; $this->mappingIds[] = $customerGroupMapping['id']; $customerGroupName = $customerGroupId; @@ -545,7 +510,7 @@ protected function getSalesChannelAndCustomerGroupCalculationRule(array $data): 'salesChannelAndCustomerGroupRule_' . $shopId . '_' . $customerGroupId, $this->context ); - $priceRuleUuid = (string) $mapping['entityUuid']; + $priceRuleUuid = (string) $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $mapping = $this->mappingService->getOrCreateMapping( @@ -554,7 +519,7 @@ protected function getSalesChannelAndCustomerGroupCalculationRule(array $data): 'salesChannelAndCustomerGroupRule_orContainer_' . $shopId . '_' . $customerGroupId, $this->context ); - $orContainerUuid = (string) $mapping['entityUuid']; + $orContainerUuid = (string) $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $mapping = $this->mappingService->getOrCreateMapping( @@ -563,7 +528,7 @@ protected function getSalesChannelAndCustomerGroupCalculationRule(array $data): 'salesChannelAndCustomerGroupRule_andContainer_' . $shopId . '_' . $customerGroupId, $this->context ); - $andContainerUuid = (string) $mapping['entityUuid']; + $andContainerUuid = (string) $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $mapping = $this->mappingService->getOrCreateMapping( @@ -572,7 +537,7 @@ protected function getSalesChannelAndCustomerGroupCalculationRule(array $data): 'salesChannelAndCustomerGroupRule_condition_' . $shopId . '_' . $customerGroupId, $this->context ); - $conditionUuid = (string) $mapping['entityUuid']; + $conditionUuid = (string) $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $rule = [ @@ -633,7 +598,7 @@ protected function getSalesChannelAndCustomerGroupCalculationRule(array $data): * * @return list> */ - protected function getShippingCosts(array $data, int $calculationType, ?array $rule): array + protected function getShippingCosts(MigrationContextInterface $migrationContext, array $data, int $calculationType, ?array $rule): array { $shippingCosts = $data['shippingCosts']; $taxRate = 0.0; @@ -644,12 +609,14 @@ protected function getShippingCosts(array $data, int $calculationType, ?array $r $convertedCosts = []; foreach ($shippingCosts as $key => $shippingCost) { if (empty($shippingCost['id'])) { - $this->loggingService->addLogEntry(new EmptyNecessaryFieldRunLog( - $this->runId, - DefaultEntities::SHIPPING_METHOD_PRICE, - $this->oldShippingMethod, - 'id' - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withEntityName(ShippingMethodPriceDefinition::ENTITY_NAME) + ->withFieldName('id') + ->withFieldSourcePath('id') + ->withSourceData($data) + ->build(EmptyNecessaryFieldRunLog::class) + ); continue; } @@ -663,7 +630,7 @@ protected function getShippingCosts(array $data, int $calculationType, ?array $r $shippingCost['id'], $this->context ); - $cost['id'] = $mapping['entityUuid']; + $cost['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $cost['calculation'] = $calculationType; @@ -679,16 +646,18 @@ protected function getShippingCosts(array $data, int $calculationType, ?array $r } if (!isset($currencyMapping)) { - $this->loggingService->addLogEntry(new EmptyNecessaryFieldRunLog( - $this->runId, - DefaultEntities::SHIPPING_METHOD_PRICE, - $shippingCost['id'], - 'currency' - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withEntityName(ShippingMethodPriceDefinition::ENTITY_NAME) + ->withFieldName('currencyId') + ->withFieldSourcePath('currencyShortName') + ->withSourceData($data) + ->build(EmptyNecessaryFieldRunLog::class) + ); continue; } - $currencyUuid = $currencyMapping['entityUuid']; + $currencyUuid = $currencyMapping['entityId']; $this->mappingIds[] = $currencyMapping['id']; $cost['currencyId'] = $currencyUuid; if (isset($shippingCosts[$key + 1])) { @@ -696,12 +665,14 @@ protected function getShippingCosts(array $data, int $calculationType, ?array $r } if (isset($shippingCost['factor']) && $shippingCost['factor'] > 0) { - $this->loggingService->addLogEntry(new UnsupportedShippingPriceLog( - $this->runId, - DefaultEntities::SHIPPING_METHOD_PRICE, - $shippingCost['id'], - $this->oldShippingMethod - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withEntityName(ShippingMethodPriceDefinition::ENTITY_NAME) + ->withFieldSourcePath('factor') + ->withSourceData($shippingCost) + ->withConvertedData($cost) + ->build(UnsupportedShippingPriceLog::class) + ); continue; } @@ -735,7 +706,7 @@ private function setCustomAvailabilityRule(array $data, array &$converted): void $ruleData = $this->getRelevantDataForAvailabilityRule($data); $jsonRuleData = \json_encode($ruleData, \JSON_THROW_ON_ERROR); - $hash = \md5($jsonRuleData); + $hash = Hasher::hash($jsonRuleData, 'md5'); $mainRuleMapping = $this->mappingService->getOrCreateMapping( $this->connectionId, @@ -746,7 +717,7 @@ private function setCustomAvailabilityRule(array $data, array &$converted): void $this->mappingIds[] = $mainRuleMapping['id']; $mainRule = [ - 'id' => (string) $mainRuleMapping['entityUuid'], + 'id' => (string) $mainRuleMapping['entityId'], 'priority' => 100, 'moduleTypes' => [ 'types' => [ @@ -774,17 +745,18 @@ private function setCustomAvailabilityRule(array $data, array &$converted): void $this->mappingIds[] = $mainAndContainerMapping['id']; $mainOrContainer = [ - 'id' => (string) $mainOrContainerMapping['entityUuid'], - 'ruleId' => (string) $mainRuleMapping['entityUuid'], + 'id' => (string) $mainOrContainerMapping['entityId'], + 'ruleId' => (string) $mainRuleMapping['entityId'], 'type' => 'orContainer', 'position' => 0, 'children' => [ [ - 'id' => (string) $mainAndContainerMapping['entityUuid'], - 'ruleId' => (string) $mainRuleMapping['entityUuid'], - 'parentId' => (string) $mainOrContainerMapping['entityUuid'], + 'id' => (string) $mainAndContainerMapping['entityId'], + 'ruleId' => (string) $mainRuleMapping['entityId'], + 'parentId' => (string) $mainOrContainerMapping['entityId'], 'type' => 'andContainer', 'position' => 0, + 'children' => [], ], ], ]; @@ -809,10 +781,11 @@ private function setCustomAvailabilityRule(array $data, array &$converted): void } /** - * @return array>> + * @return list, children: list>}> */ private function getDayOfWeekChildren(int $from, int $to, string $ruleId, string $parentId): array { + /** @var list, children: list>}> $values */ $values = []; $oldTo = null; if ($from > $to) { @@ -830,7 +803,7 @@ private function getDayOfWeekChildren(int $from, int $to, string $ruleId, string } /** - * @param array $values + * @param list, children: list>}> $values */ private function setDayOfWeekValues(array &$values, int $from, int $to, string $ruleId, string $parentId): void { @@ -844,7 +817,7 @@ private function setDayOfWeekValues(array &$values, int $from, int $to, string $ ); $value = [ - 'id' => $dayMapping['entityUuid'], + 'id' => (string) $dayMapping['entityId'], 'type' => 'dayOfWeek', 'ruleId' => $ruleId, 'parentId' => $parentId, @@ -852,8 +825,10 @@ private function setDayOfWeekValues(array &$values, int $from, int $to, string $ 'operator' => '=', 'dayOfWeek' => $day, ], + 'children' => [], ]; + // @phpstan-ignore-next-line parameterByRef.type $values[] = $value; } } @@ -907,7 +882,7 @@ private function setWeekdayCondition( $this->mappingIds[] = $dayOfWeekOrContainerMapping['id']; $dayOfWeekOrContainer = [ - 'id' => $dayOfWeekOrContainerMapping['entityUuid'], + 'id' => $dayOfWeekOrContainerMapping['entityId'], 'ruleId' => $mainRuleUuid, 'parentId' => $mainAndContainerUuid, 'type' => 'orContainer', @@ -967,12 +942,13 @@ private function setBindTimeCondition( } $condition = [ - 'id' => $conditionMapping['entityUuid'], + 'id' => $conditionMapping['entityId'], 'ruleId' => $mainRuleUuid, 'parentId' => $mainAndContainerUuid, 'position' => ++$position, 'type' => 'timeRange', 'value' => $value, + 'children' => [], ]; $mainOrContainer['children'][0]['children'][] = $condition; @@ -1003,7 +979,7 @@ private function setLastStockCondition( ); $condition = [ - 'id' => $conditionMapping['entityUuid'], + 'id' => $conditionMapping['entityId'], 'ruleId' => $mainRuleUuid, 'parentId' => $mainAndContainerUuid, 'type' => 'cartLineItemClearanceSale', @@ -1011,6 +987,7 @@ private function setLastStockCondition( 'value' => [ 'clearanceSale' => true, ], + 'children' => [], ]; $mainOrContainer['children'][0]['children'][] = $condition; @@ -1049,7 +1026,7 @@ private function setOtherConditions( ); $condition = [ - 'id' => $conditionMapping['entityUuid'], + 'id' => $conditionMapping['entityId'], 'ruleId' => $mainRuleUuid, 'parentId' => $mainAndContainerUuid, 'type' => $conditionValueMapping[$key]['type'], @@ -1058,8 +1035,10 @@ private function setOtherConditions( 'operator' => $conditionValueMapping[$key]['operator'], $conditionValueMapping[$key]['value'] => (float) $data, ], + 'children' => [], ]; + // @phpstan-ignore-next-line parameterByRef.type $mainOrContainer['children'][0]['children'][] = $condition; } } @@ -1098,7 +1077,7 @@ private function setShippingCountries(array &$ruleData, string $hash, int &$posi } $condition = [ - 'id' => $conditionMapping['entityUuid'], + 'id' => $conditionMapping['entityId'], 'ruleId' => $mainRuleUuid, 'parentId' => $mainAndContainerUuid, 'type' => 'customerShippingCountry', @@ -1107,6 +1086,7 @@ private function setShippingCountries(array &$ruleData, string $hash, int &$posi 'operator' => '=', 'countryIds' => $countries, ], + 'children' => [], ]; $mainOrContainer['children'][0]['children'][] = $condition; @@ -1146,7 +1126,7 @@ private function setPaymentMethods(array &$ruleData, string $hash, int &$positio } $this->mappingIds[] = $paymentMethodMapping['id']; - $paymentMethods[] = $paymentMethodMapping['entityUuid']; + $paymentMethods[] = $paymentMethodMapping['entityId']; } if (empty($paymentMethods)) { @@ -1154,7 +1134,7 @@ private function setPaymentMethods(array &$ruleData, string $hash, int &$positio } $condition = [ - 'id' => $conditionMapping['entityUuid'], + 'id' => $conditionMapping['entityId'], 'ruleId' => $mainRuleUuid, 'parentId' => $mainAndContainerUuid, 'type' => 'paymentMethod', @@ -1163,6 +1143,7 @@ private function setPaymentMethods(array &$ruleData, string $hash, int &$positio 'operator' => '=', 'paymentMethodIds' => $paymentMethods, ], + 'children' => [], ]; $mainOrContainer['children'][0]['children'][] = $condition; @@ -1202,7 +1183,7 @@ private function setExcludedCategories(array &$ruleData, string $hash, int &$pos } $this->mappingIds[] = $categoryMapping['id']; - $excludedCategories[] = $categoryMapping['entityUuid']; + $excludedCategories[] = $categoryMapping['entityId']; } if (empty($excludedCategories)) { @@ -1210,7 +1191,7 @@ private function setExcludedCategories(array &$ruleData, string $hash, int &$pos } $condition = [ - 'id' => $conditionMapping['entityUuid'], + 'id' => $conditionMapping['entityId'], 'ruleId' => $mainRuleUuid, 'parentId' => $mainAndContainerUuid, 'type' => 'cartLineItemInCategory', @@ -1219,6 +1200,7 @@ private function setExcludedCategories(array &$ruleData, string $hash, int &$pos 'operator' => '!=', 'categoryIds' => $excludedCategories, ], + 'children' => [], ]; $mainOrContainer['children'][0]['children'][] = $condition; @@ -1249,11 +1231,12 @@ private function setFreeShipping( ); $condition = [ - 'id' => $conditionMapping['entityUuid'], + 'id' => $conditionMapping['entityId'], 'ruleId' => $mainRuleUuid, 'parentId' => $mainAndContainerUuid, 'type' => 'cartHasDeliveryFreeItem', 'position' => ++$position, + 'children' => [], ]; $mainOrContainer['children'][0]['children'][] = $condition; diff --git a/src/Profile/Shopware/Converter/ShopwareConverter.php b/src/Profile/Shopware/Converter/ShopwareConverter.php index e01821c5a..e0549101f 100644 --- a/src/Profile/Shopware/Converter/ShopwareConverter.php +++ b/src/Profile/Shopware/Converter/ShopwareConverter.php @@ -92,24 +92,6 @@ protected function checkForEmptyRequiredDataFields(array $rawData, array $requir return $emptyFields; } - /** - * @param array $converted - * @param array $requiredDataFields - * - * @return list - */ - protected function checkForEmptyRequiredConvertedFields(array $converted, array $requiredDataFields): array - { - $emptyFields = []; - foreach ($requiredDataFields as $requiredDataFieldKey => $requiredDataFieldValue) { - if (!isset($converted[$requiredDataFieldKey]) || $converted[$requiredDataFieldKey] === '') { - $emptyFields[] = $requiredDataFieldValue; - } - } - - return $emptyFields; - } - protected function validDate(string $value): bool { try { @@ -148,7 +130,7 @@ protected function getAttributes( } $connection = $this->migrationContext->getConnection(); - if ($context !== null && $connection !== null) { + if ($context !== null) { $connectionId = $connection->getId(); $mapping = $this->mappingService->getMapping( $connectionId, diff --git a/src/Profile/Shopware/Converter/TranslationConverter.php b/src/Profile/Shopware/Converter/TranslationConverter.php index c0e99804a..9a0ee0ab5 100644 --- a/src/Profile/Shopware/Converter/TranslationConverter.php +++ b/src/Profile/Shopware/Converter/TranslationConverter.php @@ -7,26 +7,33 @@ namespace SwagMigrationAssistant\Profile\Shopware\Converter; +use Shopware\Core\Content\Category\Aggregate\CategoryTranslation\CategoryTranslationDefinition; use Shopware\Core\Content\Category\CategoryDefinition; +use Shopware\Core\Content\Media\Aggregate\MediaTranslation\MediaTranslationDefinition; use Shopware\Core\Content\Media\MediaDefinition; use Shopware\Core\Content\Product\Aggregate\ProductManufacturer\ProductManufacturerDefinition; +use Shopware\Core\Content\Product\Aggregate\ProductManufacturerTranslation\ProductManufacturerTranslationDefinition; +use Shopware\Core\Content\Product\Aggregate\ProductTranslation\ProductTranslationDefinition; use Shopware\Core\Content\Product\ProductDefinition; use Shopware\Core\Content\Property\Aggregate\PropertyGroupOption\PropertyGroupOptionDefinition; +use Shopware\Core\Content\Property\Aggregate\PropertyGroupOptionTranslation\PropertyGroupOptionTranslationDefinition; +use Shopware\Core\Content\Property\Aggregate\PropertyGroupTranslation\PropertyGroupTranslationDefinition; use Shopware\Core\Content\Property\PropertyGroupDefinition; use Shopware\Core\Framework\Context; use Shopware\Core\Framework\Log\Package; +use Shopware\Core\System\Unit\Aggregate\UnitTranslation\UnitTranslationDefinition; use Shopware\Core\System\Unit\UnitDefinition; use SwagMigrationAssistant\Migration\Connection\Helper\ConnectionNameSanitizer; use SwagMigrationAssistant\Migration\Converter\ConvertStruct; use SwagMigrationAssistant\Migration\DataSelection\DefaultEntities; use SwagMigrationAssistant\Migration\Logging\Log\AssociationRequiredMissingLog; -use SwagMigrationAssistant\Migration\Logging\Log\EmptyNecessaryFieldRunLog; -use SwagMigrationAssistant\Migration\Logging\Log\InvalidUnserializedData; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogBuilder; +use SwagMigrationAssistant\Migration\Logging\Log\InvalidUnserializedDataLog; use SwagMigrationAssistant\Migration\Logging\LoggingServiceInterface; use SwagMigrationAssistant\Migration\Mapping\Lookup\LanguageLookup; use SwagMigrationAssistant\Migration\Mapping\MappingServiceInterface; use SwagMigrationAssistant\Migration\MigrationContextInterface; -use SwagMigrationAssistant\Profile\Shopware\Logging\Log\UnsupportedTranslationType; +use SwagMigrationAssistant\Profile\Shopware\Logging\Log\UnsupportedTranslationTypeLog; #[Package('fundamentals@after-sales')] abstract class TranslationConverter extends ShopwareConverter @@ -56,21 +63,7 @@ public function convert( $this->runId = $migrationContext->getRunUuid(); $connection = $migrationContext->getConnection(); - $this->connectionId = ''; - if ($connection !== null) { - $this->connectionId = $connection->getId(); - } - - if (!isset($data['locale'])) { - $this->loggingService->addLogEntry(new EmptyNecessaryFieldRunLog( - $this->runId, - DefaultEntities::TRANSLATION, - $data['id'], - 'locale' - )); - - return new ConvertStruct(null, $data); - } + $this->connectionId = $connection->getId(); switch ($data['objecttype']) { case 'article': @@ -97,12 +90,11 @@ public function convert( } $this->loggingService->addLogEntry( - new UnsupportedTranslationType( - $migrationContext->getRunUuid(), - $data['objecttype'], - DefaultEntities::TRANSLATION, - $data['id'] - ) + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withEntityName('unknown_translation') + ->withFieldSourcePath('objecttype') + ->withSourceData($data) + ->build(UnsupportedTranslationTypeLog::class) ); return new ConvertStruct(null, $data); @@ -133,17 +125,17 @@ protected function createProductTranslation(array &$data): ConvertStruct if ($mapping === null) { $this->loggingService->addLogEntry( - new AssociationRequiredMissingLog( - $this->runId, - DefaultEntities::PRODUCT, - $data['id'], - DefaultEntities::TRANSLATION - ) + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(ProductTranslationDefinition::ENTITY_NAME) + ->withFieldName('productId') + ->withFieldSourcePath('objectkey') + ->withSourceData($sourceData) + ->build(AssociationRequiredMissingLog::class) ); return new ConvertStruct(null, $sourceData); } - $product['id'] = $mapping['entityUuid']; + $product['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $product['entityDefinitionClass'] = ProductDefinition::class; @@ -204,13 +196,15 @@ protected function createProductTranslation(array &$data): ConvertStruct $this->context, $this->checksum ); - $productTranslation['id'] = $this->mainMapping['entityUuid']; + $productTranslation['id'] = $this->mainMapping['entityId']; unset($data['id']); - $languageUuid = $this->languageLookup->get($data['locale'], $this->context); - if ($languageUuid !== null) { - $productTranslation['languageId'] = $languageUuid; - $product['translations'][$languageUuid] = $productTranslation; + if (isset($data['locale'])) { + $languageUuid = $this->languageLookup->get($data['locale'], $this->context); + if ($languageUuid !== null) { + $productTranslation['languageId'] = $languageUuid; + $product['translations'][$languageUuid] = $productTranslation; + } } unset($data['name'], $data['locale']); @@ -244,17 +238,17 @@ protected function createProductVariantTranslation(array &$data): ConvertStruct if ($mapping === null) { $this->loggingService->addLogEntry( - new AssociationRequiredMissingLog( - $this->runId, - DefaultEntities::PRODUCT, - $data['id'], - DefaultEntities::TRANSLATION - ) + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(ProductTranslationDefinition::ENTITY_NAME) + ->withFieldName('productId') + ->withFieldSourcePath('ordernumber') + ->withSourceData($sourceData) + ->build(AssociationRequiredMissingLog::class) ); return new ConvertStruct(null, $sourceData); } - $product['id'] = $mapping['entityUuid']; + $product['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $product['entityDefinitionClass'] = ProductDefinition::class; @@ -283,7 +277,7 @@ protected function createProductVariantTranslation(array &$data): ConvertStruct $this->context, $this->checksum ); - $productTranslation['id'] = $this->mainMapping['entityUuid']; + $productTranslation['id'] = $this->mainMapping['entityId']; unset($data['id']); $languageUuid = $this->languageLookup->get($data['locale'], $this->context); @@ -320,17 +314,17 @@ protected function createManufacturerProductTranslation(array $data): ConvertStr if ($mapping === null) { $this->loggingService->addLogEntry( - new AssociationRequiredMissingLog( - $this->runId, - DefaultEntities::PRODUCT_MANUFACTURER, - $data['id'], - DefaultEntities::TRANSLATION - ) + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(ProductManufacturerTranslationDefinition::ENTITY_NAME) + ->withFieldName('productManufacturerId') + ->withFieldSourcePath('objectkey') + ->withSourceData($sourceData) + ->build(AssociationRequiredMissingLog::class) ); return new ConvertStruct(null, $sourceData); } - $manufacturer['id'] = $mapping['entityUuid']; + $manufacturer['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $manufacturer['entityDefinitionClass'] = ProductManufacturerDefinition::class; @@ -347,7 +341,7 @@ protected function createManufacturerProductTranslation(array $data): ConvertStr $this->context, $this->checksum ); - $manufacturerTranslation['id'] = $this->mainMapping['entityUuid']; + $manufacturerTranslation['id'] = $this->mainMapping['entityId']; unset($data['id'], $data['objectkey']); $this->convertValue($manufacturerTranslation, 'name', $data, 'name'); @@ -402,17 +396,17 @@ protected function createUnitTranslation(array $data): ConvertStruct if ($mapping === null) { $this->loggingService->addLogEntry( - new AssociationRequiredMissingLog( - $this->runId, - DefaultEntities::UNIT, - $data['id'], - DefaultEntities::TRANSLATION - ) + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(UnitTranslationDefinition::ENTITY_NAME) + ->withFieldName('unitId') + ->withFieldSourcePath('objectkey') + ->withSourceData($sourceData) + ->build(AssociationRequiredMissingLog::class) ); return new ConvertStruct(null, $sourceData); } - $unit['id'] = $mapping['entityUuid']; + $unit['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $unit['entityDefinitionClass'] = UnitDefinition::class; @@ -429,7 +423,7 @@ protected function createUnitTranslation(array $data): ConvertStruct $this->context, $this->checksum ); - $unitTranslation['id'] = $this->mainMapping['entityUuid']; + $unitTranslation['id'] = $this->mainMapping['entityId']; $objectData = \array_pop($objectData); @@ -489,17 +483,17 @@ protected function createCategoryTranslation(array $data): ConvertStruct if ($mapping === null) { $this->loggingService->addLogEntry( - new AssociationRequiredMissingLog( - $this->runId, - DefaultEntities::CATEGORY, - $data['id'], - DefaultEntities::TRANSLATION - ) + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(CategoryTranslationDefinition::ENTITY_NAME) + ->withFieldName('categoryId') + ->withFieldSourcePath('objectkey') + ->withSourceData($sourceData) + ->build(AssociationRequiredMissingLog::class) ); return new ConvertStruct(null, $sourceData); } - $category['id'] = $mapping['entityUuid']; + $category['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $category['entityDefinitionClass'] = CategoryDefinition::class; @@ -523,7 +517,7 @@ protected function createCategoryTranslation(array $data): ConvertStruct $this->context, $this->checksum ); - $categoryTranslation['id'] = $this->mainMapping['entityUuid']; + $categoryTranslation['id'] = $this->mainMapping['entityId']; $this->convertValue($categoryTranslation, 'name', $objectData, 'description'); $this->convertValue($categoryTranslation, 'description', $objectData, 'cmstext'); @@ -586,17 +580,17 @@ protected function createConfiguratorOptionTranslation(array $data): ConvertStru if ($mapping === null) { $this->loggingService->addLogEntry( - new AssociationRequiredMissingLog( - $this->runId, - DefaultEntities::PROPERTY_GROUP_OPTION, - $data['id'], - DefaultEntities::TRANSLATION - ) + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(PropertyGroupOptionTranslationDefinition::ENTITY_NAME) + ->withFieldName('propertyGroupOptionId') + ->withFieldSourcePath('objectkey') + ->withSourceData($sourceData) + ->build(AssociationRequiredMissingLog::class) ); return new ConvertStruct(null, $sourceData); } - $configuratorOption['id'] = $mapping['entityUuid']; + $configuratorOption['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $configuratorOption['entityDefinitionClass'] = PropertyGroupOptionDefinition::class; @@ -612,7 +606,7 @@ protected function createConfiguratorOptionTranslation(array $data): ConvertStru $data['id'], $this->context ); - $propertyGroupOptionTranslation['id'] = $this->mainMapping['entityUuid']; + $propertyGroupOptionTranslation['id'] = $this->mainMapping['entityId']; foreach ($objectData as $key => $value) { if ($key === 'name') { @@ -665,17 +659,17 @@ protected function createConfiguratorOptionGroupTranslation(array $data): Conver if ($mapping === null) { $this->loggingService->addLogEntry( - new AssociationRequiredMissingLog( - $this->runId, - DefaultEntities::PROPERTY_GROUP, - $data['id'], - DefaultEntities::TRANSLATION - ) + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(PropertyGroupTranslationDefinition::ENTITY_NAME) + ->withFieldName('propertyGroupId') + ->withFieldSourcePath('objectkey') + ->withSourceData($sourceData) + ->build(AssociationRequiredMissingLog::class) ); return new ConvertStruct(null, $sourceData); } - $configuratorOptionGroup['id'] = $mapping['entityUuid']; + $configuratorOptionGroup['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $configuratorOptionGroup['entityDefinitionClass'] = PropertyGroupDefinition::class; @@ -692,7 +686,7 @@ protected function createConfiguratorOptionGroupTranslation(array $data): Conver $this->context, $this->checksum ); - $propertyGroupTranslation['id'] = $this->mainMapping['entityUuid']; + $propertyGroupTranslation['id'] = $this->mainMapping['entityId']; foreach ($objectData as $key => $value) { if ($key === 'name') { @@ -747,17 +741,17 @@ protected function createPropertyValueTranslation(array $data): ConvertStruct if ($mapping === null) { $this->loggingService->addLogEntry( - new AssociationRequiredMissingLog( - $this->runId, - DefaultEntities::PROPERTY_GROUP_OPTION, - $data['id'], - DefaultEntities::TRANSLATION - ) + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(PropertyGroupOptionTranslationDefinition::ENTITY_NAME) + ->withFieldName('propertyGroupOptionId') + ->withFieldSourcePath('objectkey') + ->withSourceData($sourceData) + ->build(AssociationRequiredMissingLog::class) ); return new ConvertStruct(null, $sourceData); } - $propertyValue['id'] = $mapping['entityUuid']; + $propertyValue['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $propertyValue['entityDefinitionClass'] = PropertyGroupOptionDefinition::class; @@ -773,7 +767,7 @@ protected function createPropertyValueTranslation(array $data): ConvertStruct $data['id'], $this->context ); - $propertyValueTranslation['id'] = $this->mainMapping['entityUuid']; + $propertyValueTranslation['id'] = $this->mainMapping['entityId']; foreach ($objectData as $key => $value) { if ($key === 'optionValue') { @@ -824,17 +818,17 @@ protected function createPropertyOptionTranslation(array $data): ConvertStruct if ($mapping === null) { $this->loggingService->addLogEntry( - new AssociationRequiredMissingLog( - $this->runId, - DefaultEntities::PROPERTY_GROUP, - $data['id'], - DefaultEntities::TRANSLATION - ) + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(PropertyGroupTranslationDefinition::ENTITY_NAME) + ->withFieldName('propertyGroupId') + ->withFieldSourcePath('objectkey') + ->withSourceData($sourceData) + ->build(AssociationRequiredMissingLog::class) ); return new ConvertStruct(null, $sourceData); } - $propertyOption['id'] = $mapping['entityUuid']; + $propertyOption['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $propertyOption['entityDefinitionClass'] = PropertyGroupDefinition::class; @@ -851,7 +845,7 @@ protected function createPropertyOptionTranslation(array $data): ConvertStruct $this->context, $this->checksum ); - $propertyOptionTranslation['id'] = $this->mainMapping['entityUuid']; + $propertyOptionTranslation['id'] = $this->mainMapping['entityId']; foreach ($objectData as $key => $value) { if ($key === 'optionName') { @@ -891,12 +885,11 @@ protected function createPropertyOptionTranslation(array $data): ConvertStruct */ protected function addAttribute(string $entityName, string $key, string $value, array &$translation, array &$objectData): void { - $connection = $this->migrationContext->getConnection(); - - if ($connection === null || $value === '') { + if ($value === '') { return; } + $connection = $this->migrationContext->getConnection(); $connectionName = ConnectionNameSanitizer::sanitize($connection->getName()); $isAttribute = \mb_strpos($key, '__attribute_'); @@ -947,22 +940,24 @@ protected function addAttribute(string $entityName, string $key, string $value, protected function unserializeTranslation(array $data, string $entity): ?array { $objectDataSerialized = $data['objectdata']; + $exception = null; try { $objectData = \unserialize($objectDataSerialized, ['allowed_classes' => false]); - } catch (\Throwable $error) { + } catch (\Throwable $e) { $objectData = null; + $exception = $e; } if (!\is_array($objectData)) { $this->loggingService->addLogEntry( - new InvalidUnserializedData( - $this->runId, - DefaultEntities::TRANSLATION, - $data['id'], - $entity, - $objectDataSerialized - ) + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName($entity) + ->withFieldSourcePath('objectdata') + ->withSourceData($data) + ->withExceptionMessage($exception?->getMessage() ?? 'Unserialization failed') + ->withExceptionTrace($exception?->getTrace() ?? []) + ->build(InvalidUnserializedDataLog::class) ); return null; @@ -991,19 +986,19 @@ protected function createProductMediaTranslation(array $data): ConvertStruct if ($mapping === null) { $this->loggingService->addLogEntry( - new AssociationRequiredMissingLog( - $this->runId, - DefaultEntities::MEDIA, - $data['mediaId'], - DefaultEntities::TRANSLATION - ) + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(MediaTranslationDefinition::ENTITY_NAME) + ->withFieldName('mediaId') + ->withFieldSourcePath('mediaId') + ->withSourceData($sourceData) + ->build(AssociationRequiredMissingLog::class) ); return new ConvertStruct(null, $sourceData); } unset($data['objectkey'], $data['mediaId']); - $media['id'] = $mapping['entityUuid']; + $media['id'] = $mapping['entityId']; $this->mappingIds[] = $mapping['id']; $media['entityDefinitionClass'] = MediaDefinition::class; @@ -1020,7 +1015,7 @@ protected function createProductMediaTranslation(array $data): ConvertStruct $this->context, $this->checksum ); - $mediaTranslation['id'] = $this->mainMapping['entityUuid']; + $mediaTranslation['id'] = $this->mainMapping['entityId']; foreach (\array_keys($objectData) as $key) { if ($key === 'description') { diff --git a/src/Profile/Shopware/Gateway/Api/Reader/TableCountReader.php b/src/Profile/Shopware/Gateway/Api/Reader/TableCountReader.php index 91af0c900..0d2fcaf0c 100644 --- a/src/Profile/Shopware/Gateway/Api/Reader/TableCountReader.php +++ b/src/Profile/Shopware/Gateway/Api/Reader/TableCountReader.php @@ -10,6 +10,7 @@ use Shopware\Core\Framework\Context; use Shopware\Core\Framework\Log\Package; use SwagMigrationAssistant\Exception\MigrationException; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogBuilder; use SwagMigrationAssistant\Migration\Logging\Log\CannotReadEntityCountLog; use SwagMigrationAssistant\Migration\Logging\LoggingService; use SwagMigrationAssistant\Migration\MigrationContextInterface; @@ -68,14 +69,11 @@ private function prepareTotals(array $result): array private function logExceptions(array $exceptionArray, MigrationContextInterface $migrationContext, Context $context): void { foreach ($exceptionArray as $exception) { - $this->loggingService->addLogEntry(new CannotReadEntityCountLog( - $migrationContext->getRunUuid(), - $exception['entity'], - $exception['table'], - $exception['condition'], - $exception['code'], - $exception['message'] - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withExceptionMessage($exception['message']) + ->build(CannotReadEntityCountLog::class) + ); } $this->loggingService->saveLogging($context); diff --git a/src/Profile/Shopware/Gateway/Api/ShopwareApiGateway.php b/src/Profile/Shopware/Gateway/Api/ShopwareApiGateway.php index 5c93752bb..cf5dcf06c 100644 --- a/src/Profile/Shopware/Gateway/Api/ShopwareApiGateway.php +++ b/src/Profile/Shopware/Gateway/Api/ShopwareApiGateway.php @@ -22,6 +22,7 @@ use SwagMigrationAssistant\Migration\Gateway\Reader\EnvironmentReaderInterface; use SwagMigrationAssistant\Migration\Gateway\Reader\ReaderRegistryInterface; use SwagMigrationAssistant\Migration\MigrationContextInterface; +use SwagMigrationAssistant\Migration\Profile\ProfileInterface; use SwagMigrationAssistant\Profile\Shopware\Gateway\ShopwareGatewayInterface; use SwagMigrationAssistant\Profile\Shopware\Gateway\TableCountReaderInterface; use SwagMigrationAssistant\Profile\Shopware\Gateway\TableReaderInterface; @@ -56,9 +57,9 @@ public function getSnippetName(): string return 'swag-migration.wizard.pages.connectionCreate.gateways.shopwareApi'; } - public function supports(MigrationContextInterface $migrationContext): bool + public function supports(ProfileInterface $profile): bool { - return $migrationContext->getProfile() instanceof ShopwareProfileInterface; + return $profile instanceof ShopwareProfileInterface; } public function read(MigrationContextInterface $migrationContext): array @@ -124,21 +125,7 @@ public function readEnvironmentInformation(MigrationContextInterface $migrationC $environmentDataArray['defaultShopLanguage'] = \str_replace('_', '-', $environmentDataArray['defaultShopLanguage']); $totals = $this->readTotals($migrationContext, $context); - - $connection = $migrationContext->getConnection(); - - if ($connection === null) { - return new EnvironmentInformation( - $profile->getSourceSystemName(), - $profile->getVersion(), - '', - [], - [], - null - ); - } - - $credentials = $connection->getCredentialFields(); + $credentials = $migrationContext->getConnection()->getCredentialFields(); if ($credentials === null) { return new EnvironmentInformation( diff --git a/src/Profile/Shopware/Gateway/Connection/ConnectionFactory.php b/src/Profile/Shopware/Gateway/Connection/ConnectionFactory.php index fa949b6a9..bf9792d2f 100644 --- a/src/Profile/Shopware/Gateway/Connection/ConnectionFactory.php +++ b/src/Profile/Shopware/Gateway/Connection/ConnectionFactory.php @@ -24,13 +24,7 @@ class ConnectionFactory implements ConnectionFactoryInterface, ResetInterface public function createApiClient(MigrationContextInterface $migrationContext): HttpClientInterface { - $connection = $migrationContext->getConnection(); - - if ($connection === null) { - throw MigrationException::noConnectionFound(); - } - - $credentials = $connection->getCredentialFields(); + $credentials = $migrationContext->getConnection()->getCredentialFields(); if (empty($credentials)) { throw MigrationException::invalidConnectionCredentials(); @@ -57,13 +51,7 @@ public function createDatabaseConnection(MigrationContextInterface $migrationCon return $this->externalConnection; } - $connection = $migrationContext->getConnection(); - - if ($connection === null) { - throw MigrationException::noConnectionFound(); - } - - $credentials = $connection->getCredentialFields(); + $credentials = $migrationContext->getConnection()->getCredentialFields(); if ($credentials === null) { throw MigrationException::invalidConnectionCredentials(); diff --git a/src/Profile/Shopware/Gateway/Local/Reader/AttributeReader.php b/src/Profile/Shopware/Gateway/Local/Reader/AttributeReader.php index cd693effe..6556dcdee 100644 --- a/src/Profile/Shopware/Gateway/Local/Reader/AttributeReader.php +++ b/src/Profile/Shopware/Gateway/Local/Reader/AttributeReader.php @@ -105,7 +105,9 @@ private function getAttributeConfiguration(string $table, MigrationContextInterf ->setParameter('table', $table); /** @var array> $attributeConfiguration */ - $attributeConfiguration = FetchModeHelper::groupUnique($query->executeQuery()->fetchAllAssociative()); + $attributeConfiguration = FetchModeHelper::groupUnique( + $query->executeQuery()->fetchAllAssociative() + ); $sql = <<getProfile() instanceof ShopwareProfileInterface; + return $profile instanceof ShopwareProfileInterface; } public function read(MigrationContextInterface $migrationContext): array diff --git a/src/Profile/Shopware/Logging/Log/DeactivatedPackLanguageLog.php b/src/Profile/Shopware/Logging/Log/DeactivatedPackLanguageLog.php index 956552f0e..99591aa06 100644 --- a/src/Profile/Shopware/Logging/Log/DeactivatedPackLanguageLog.php +++ b/src/Profile/Shopware/Logging/Log/DeactivatedPackLanguageLog.php @@ -8,18 +8,14 @@ namespace SwagMigrationAssistant\Profile\Shopware\Logging\Log; use Shopware\Core\Framework\Log\Package; -use SwagMigrationAssistant\Migration\Logging\Log\BaseRunLogEntry; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; #[Package('fundamentals@after-sales')] -class DeactivatedPackLanguageLog extends BaseRunLogEntry +readonly class DeactivatedPackLanguageLog extends AbstractMigrationLogEntry { - public function __construct( - string $runId, - string $entity, - string $sourceId, - private readonly string $languageId, - ) { - parent::__construct($runId, $entity, $sourceId); + public function isUserFixable(): bool + { + return false; } public function getLevel(): string @@ -31,33 +27,4 @@ public function getCode(): string { return 'SWAG_MIGRATION__DEACTIVATED_PACK_LANGUAGE'; } - - public function getTitle(): string - { - return 'Deactivated pack language'; - } - - /** - * @return array{entity: ?string, sourceId: ?string, packLanguage: string} - */ - public function getParameters(): array - { - return [ - 'entity' => $this->getEntity(), - 'sourceId' => $this->getSourceId(), - 'packLanguage' => $this->languageId, - ]; - } - - public function getDescription(): string - { - $args = $this->getParameters(); - - return \sprintf( - 'Language for %s with source id "%s" has been set to default language. The language with id "%s" is not activated for sales channels by "Language pack" plugin.', - $args['entity'], - $args['sourceId'], - $args['packLanguage'] - ); - } } diff --git a/src/Profile/Shopware/Logging/Log/InvalidEmailAddressLog.php b/src/Profile/Shopware/Logging/Log/InvalidEmailAddressLog.php index 23be78316..f35bda3ee 100644 --- a/src/Profile/Shopware/Logging/Log/InvalidEmailAddressLog.php +++ b/src/Profile/Shopware/Logging/Log/InvalidEmailAddressLog.php @@ -8,18 +8,14 @@ namespace SwagMigrationAssistant\Profile\Shopware\Logging\Log; use Shopware\Core\Framework\Log\Package; -use SwagMigrationAssistant\Migration\Logging\Log\BaseRunLogEntry; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; #[Package('fundamentals@after-sales')] -class InvalidEmailAddressLog extends BaseRunLogEntry +readonly class InvalidEmailAddressLog extends AbstractMigrationLogEntry { - public function __construct( - string $runId, - string $entity, - string $sourceId, - private readonly string $email, - ) { - parent::__construct($runId, $entity, $sourceId); + public function isUserFixable(): bool + { + return false; } public function getLevel(): string @@ -31,33 +27,4 @@ public function getCode(): string { return 'SWAG_MIGRATION__INVALID_EMAIL_ADDRESS'; } - - public function getTitle(): string - { - return 'Invalid Email address'; - } - - /** - * @return array{entity: ?string, sourceId: ?string, email: string} - */ - public function getParameters(): array - { - return [ - 'entity' => $this->getEntity(), - 'sourceId' => $this->getSourceId(), - 'email' => $this->email, - ]; - } - - public function getDescription(): string - { - $args = $this->getParameters(); - - return \sprintf( - '%s with source id "%s" could not be converted because of invalid email address: %s.', - $args['entity'], - $args['sourceId'], - $args['email'] - ); - } } diff --git a/src/Profile/Shopware/Logging/Log/UnsupportedMailTemplateType.php b/src/Profile/Shopware/Logging/Log/UnsupportedMailTemplateType.php deleted file mode 100644 index 97db7f0e1..000000000 --- a/src/Profile/Shopware/Logging/Log/UnsupportedMailTemplateType.php +++ /dev/null @@ -1,60 +0,0 @@ - - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace SwagMigrationAssistant\Profile\Shopware\Logging\Log; - -use Shopware\Core\Framework\Log\Package; -use SwagMigrationAssistant\Migration\Logging\Log\BaseRunLogEntry; - -#[Package('fundamentals@after-sales')] -class UnsupportedMailTemplateType extends BaseRunLogEntry -{ - public function __construct( - string $runId, - string $sourceId, - private readonly string $type, - ) { - parent::__construct($runId, null, $sourceId); - } - - public function getLevel(): string - { - return self::LOG_LEVEL_INFO; - } - - public function getCode(): string - { - return 'SWAG_MIGRATION__SHOPWARE_UNSUPPORTED_MAIL_TEMPLATE_TYPE'; - } - - public function getTitle(): string - { - return 'Unsupported mail type'; - } - - /** - * @return array{sourceId: ?string, type: string} - */ - public function getParameters(): array - { - return [ - 'sourceId' => $this->getSourceId(), - 'type' => $this->type, - ]; - } - - public function getDescription(): string - { - $args = $this->getParameters(); - - return \sprintf( - 'MailTemplate-Entity with source id "%s" could not be converted because of unsupported type: %s.', - $args['sourceId'], - $args['type'] - ); - } -} diff --git a/src/Profile/Shopware/Logging/Log/UnsupportedMailTemplateTypeLog.php b/src/Profile/Shopware/Logging/Log/UnsupportedMailTemplateTypeLog.php new file mode 100644 index 000000000..5bf8d8127 --- /dev/null +++ b/src/Profile/Shopware/Logging/Log/UnsupportedMailTemplateTypeLog.php @@ -0,0 +1,30 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Profile\Shopware\Logging\Log; + +use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; + +#[Package('fundamentals@after-sales')] +readonly class UnsupportedMailTemplateTypeLog extends AbstractMigrationLogEntry +{ + public function isUserFixable(): bool + { + return false; + } + + public function getLevel(): string + { + return self::LOG_LEVEL_INFO; + } + + public function getCode(): string + { + return 'SWAG_MIGRATION__SHOPWARE_UNSUPPORTED_MAIL_TEMPLATE_TYPE'; + } +} diff --git a/src/Profile/Shopware/Logging/Log/UnsupportedNumberRangeTypeLog.php b/src/Profile/Shopware/Logging/Log/UnsupportedNumberRangeTypeLog.php index 7f27e57ee..f7ca603a6 100644 --- a/src/Profile/Shopware/Logging/Log/UnsupportedNumberRangeTypeLog.php +++ b/src/Profile/Shopware/Logging/Log/UnsupportedNumberRangeTypeLog.php @@ -8,18 +8,14 @@ namespace SwagMigrationAssistant\Profile\Shopware\Logging\Log; use Shopware\Core\Framework\Log\Package; -use SwagMigrationAssistant\Migration\Logging\Log\BaseRunLogEntry; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; #[Package('fundamentals@after-sales')] -class UnsupportedNumberRangeTypeLog extends BaseRunLogEntry +readonly class UnsupportedNumberRangeTypeLog extends AbstractMigrationLogEntry { - public function __construct( - string $runId, - string $entity, - string $sourceId, - private readonly string $type, - ) { - parent::__construct($runId, $entity, $sourceId); + public function isUserFixable(): bool + { + return false; } public function getLevel(): string @@ -31,32 +27,4 @@ public function getCode(): string { return 'SWAG_MIGRATION__SHOPWARE_UNSUPPORTED_NUMBER_RANGE_TYPE'; } - - public function getTitle(): string - { - return 'Unsupported number range type'; - } - - /** - * @return array{entity: ?string, sourceId: ?string, type: string} - */ - public function getParameters(): array - { - return [ - 'entity' => $this->getEntity(), - 'sourceId' => $this->getSourceId(), - 'type' => $this->type, - ]; - } - - public function getDescription(): string - { - $args = $this->getParameters(); - - return \sprintf( - 'NumberRange-Entity with source id "%s" could not be converted because of unsupported type: %s.', - $args['sourceId'], - $args['type'] - ); - } } diff --git a/src/Profile/Shopware/Logging/Log/UnsupportedTranslationType.php b/src/Profile/Shopware/Logging/Log/UnsupportedSeoUrlTypeLog.php similarity index 85% rename from src/Profile/Shopware/Logging/Log/UnsupportedTranslationType.php rename to src/Profile/Shopware/Logging/Log/UnsupportedSeoUrlTypeLog.php index 6f61a5bd6..adc268f1d 100644 --- a/src/Profile/Shopware/Logging/Log/UnsupportedTranslationType.php +++ b/src/Profile/Shopware/Logging/Log/UnsupportedSeoUrlTypeLog.php @@ -8,10 +8,10 @@ namespace SwagMigrationAssistant\Profile\Shopware\Logging\Log; use Shopware\Core\Framework\Log\Package; -use SwagMigrationAssistant\Migration\Logging\Log\UnsupportedObjectType; +use SwagMigrationAssistant\Migration\Logging\Log\UnsupportedObjectTypeLog; #[Package('fundamentals@after-sales')] -class UnsupportedTranslationType extends UnsupportedObjectType +readonly class UnsupportedSeoUrlTypeLog extends UnsupportedObjectTypeLog { public function getLevel(): string { diff --git a/src/Profile/Shopware/Logging/Log/UnsupportedShippingCalculationType.php b/src/Profile/Shopware/Logging/Log/UnsupportedShippingCalculationType.php deleted file mode 100644 index 8eaf9fc06..000000000 --- a/src/Profile/Shopware/Logging/Log/UnsupportedShippingCalculationType.php +++ /dev/null @@ -1,62 +0,0 @@ - - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace SwagMigrationAssistant\Profile\Shopware\Logging\Log; - -use Shopware\Core\Framework\Log\Package; -use SwagMigrationAssistant\Migration\Logging\Log\BaseRunLogEntry; - -#[Package('fundamentals@after-sales')] -class UnsupportedShippingCalculationType extends BaseRunLogEntry -{ - public function __construct( - string $runId, - string $entity, - string $sourceId, - private readonly string $type, - ) { - parent::__construct($runId, $entity, $sourceId); - } - - public function getLevel(): string - { - return self::LOG_LEVEL_WARNING; - } - - public function getCode(): string - { - return 'SWAG_MIGRATION__SHOPWARE_UNSUPPORTED_SHIPPING_CALCULATION_TYPE'; - } - - public function getTitle(): string - { - return 'Unsupported shipping calculation type'; - } - - /** - * @return array{entity: ?string, sourceId: ?string, type: string} - */ - public function getParameters(): array - { - return [ - 'entity' => $this->getEntity(), - 'sourceId' => $this->getSourceId(), - 'type' => $this->type, - ]; - } - - public function getDescription(): string - { - $args = $this->getParameters(); - - return \sprintf( - 'ShippingMethod-Entity with source id "%s" could not be converted because of unsupported calculation type "%s".', - $args['sourceId'], - $args['type'] - ); - } -} diff --git a/src/Profile/Shopware/Logging/Log/UnsupportedShippingCalculationTypeLog.php b/src/Profile/Shopware/Logging/Log/UnsupportedShippingCalculationTypeLog.php new file mode 100644 index 000000000..138945fcb --- /dev/null +++ b/src/Profile/Shopware/Logging/Log/UnsupportedShippingCalculationTypeLog.php @@ -0,0 +1,30 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SwagMigrationAssistant\Profile\Shopware\Logging\Log; + +use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; + +#[Package('fundamentals@after-sales')] +readonly class UnsupportedShippingCalculationTypeLog extends AbstractMigrationLogEntry +{ + public function isUserFixable(): bool + { + return false; + } + + public function getLevel(): string + { + return self::LOG_LEVEL_WARNING; + } + + public function getCode(): string + { + return 'SWAG_MIGRATION__SHOPWARE_UNSUPPORTED_SHIPPING_CALCULATION_TYPE'; + } +} diff --git a/src/Profile/Shopware/Logging/Log/UnsupportedShippingPriceLog.php b/src/Profile/Shopware/Logging/Log/UnsupportedShippingPriceLog.php index 20ef6a029..f77ee718a 100644 --- a/src/Profile/Shopware/Logging/Log/UnsupportedShippingPriceLog.php +++ b/src/Profile/Shopware/Logging/Log/UnsupportedShippingPriceLog.php @@ -8,18 +8,14 @@ namespace SwagMigrationAssistant\Profile\Shopware\Logging\Log; use Shopware\Core\Framework\Log\Package; -use SwagMigrationAssistant\Migration\Logging\Log\BaseRunLogEntry; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; #[Package('fundamentals@after-sales')] -class UnsupportedShippingPriceLog extends BaseRunLogEntry +readonly class UnsupportedShippingPriceLog extends AbstractMigrationLogEntry { - public function __construct( - string $runId, - string $entity, - string $sourceId, - private readonly string $shippingMethodId, - ) { - parent::__construct($runId, $entity, $sourceId); + public function isUserFixable(): bool + { + return false; } public function getLevel(): string @@ -31,32 +27,4 @@ public function getCode(): string { return 'SWAG_MIGRATION__SHOPWARE_UNSUPPORTED_SHIPPING_PRICE'; } - - public function getTitle(): string - { - return 'Unsupported shipping factor price calculation'; - } - - /** - * @return array{entity: ?string, sourceId: ?string, shippingMethodId: string} - */ - public function getParameters(): array - { - return [ - 'entity' => $this->getEntity(), - 'sourceId' => $this->getSourceId(), - 'shippingMethodId' => $this->shippingMethodId, - ]; - } - - public function getDescription(): string - { - $args = $this->getParameters(); - - return \sprintf( - 'ShippingPrice-Entity with source id "%s" of shipping method "%s" could not be converted because of unsupported factor price calculation.', - $args['sourceId'], - $args['shippingMethodId'] - ); - } } diff --git a/src/Profile/Shopware/Logging/Log/UnsupportedSeoUrlType.php b/src/Profile/Shopware/Logging/Log/UnsupportedTranslationTypeLog.php similarity index 85% rename from src/Profile/Shopware/Logging/Log/UnsupportedSeoUrlType.php rename to src/Profile/Shopware/Logging/Log/UnsupportedTranslationTypeLog.php index 2ed91dbee..c7bb3c133 100644 --- a/src/Profile/Shopware/Logging/Log/UnsupportedSeoUrlType.php +++ b/src/Profile/Shopware/Logging/Log/UnsupportedTranslationTypeLog.php @@ -8,10 +8,10 @@ namespace SwagMigrationAssistant\Profile\Shopware\Logging\Log; use Shopware\Core\Framework\Log\Package; -use SwagMigrationAssistant\Migration\Logging\Log\UnsupportedObjectType; +use SwagMigrationAssistant\Migration\Logging\Log\UnsupportedObjectTypeLog; #[Package('fundamentals@after-sales')] -class UnsupportedSeoUrlType extends UnsupportedObjectType +readonly class UnsupportedTranslationTypeLog extends UnsupportedObjectTypeLog { public function getLevel(): string { diff --git a/src/Profile/Shopware/Media/LocalMediaProcessor.php b/src/Profile/Shopware/Media/LocalMediaProcessor.php index e140d9f38..d23712cf7 100644 --- a/src/Profile/Shopware/Media/LocalMediaProcessor.php +++ b/src/Profile/Shopware/Media/LocalMediaProcessor.php @@ -10,12 +10,13 @@ use Doctrine\DBAL\Connection; use Shopware\Core\Content\Media\File\FileSaver; use Shopware\Core\Content\Media\File\MediaFile; +use Shopware\Core\Content\Media\MediaDefinition; use Shopware\Core\Content\Media\MediaException; use Shopware\Core\Framework\Context; use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository; use Shopware\Core\Framework\Log\Package; use Shopware\Core\Framework\Uuid\Uuid; -use SwagMigrationAssistant\Migration\DataSelection\DefaultEntities; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogBuilder; use SwagMigrationAssistant\Migration\Logging\Log\CannotGetFileRunLog; use SwagMigrationAssistant\Migration\Logging\Log\ExceptionRunLog; use SwagMigrationAssistant\Migration\Logging\Log\MimeTypeErrorLog; @@ -129,12 +130,17 @@ private function copyMediaFiles( if ($resolver === null) { $mappedWorkload[$mediaId]->setState(MediaProcessWorkloadStruct::ERROR_STATE); - $this->loggingService->addLogEntry(new CannotGetFileRunLog( - $mappedWorkload[$mediaId]->getRunId(), - DefaultEntities::MEDIA, - $mediaId, - $sourcePath - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withEntityName(MediaDefinition::ENTITY_NAME) + ->withSourceData([ + 'media_id' => $mediaId, + 'source_path' => $sourcePath, + 'media' => $mediaFile, + ]) + ->withEntityId($mediaId) + ->build(CannotGetFileRunLog::class) + ); $processedMedia[] = $mediaId; $failedMedia[] = $mediaId; @@ -147,11 +153,18 @@ private function copyMediaFiles( if ($filePath === false) { $failedMedia[] = $mediaId; $mappedWorkload[$mediaId]->setState(MediaProcessWorkloadStruct::ERROR_STATE); - $this->loggingService->addLogEntry(new TemporaryFileErrorLog( - $mappedWorkload[$mediaId]->getRunId(), - DefaultEntities::MEDIA, - $mediaId, - )); + + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withEntityName(MediaDefinition::ENTITY_NAME) + ->withSourceData([ + 'media_id' => $mediaId, + 'source_path' => $sourcePath, + 'media' => $mediaFile, + ]) + ->withEntityId($mediaId) + ->build(TemporaryFileErrorLog::class) + ); continue; } @@ -162,6 +175,7 @@ private function copyMediaFiles( try { $this->persistFileToMedia( + $migrationContext, $filePath, $mediaFile, $fileSize, @@ -175,22 +189,35 @@ private function copyMediaFiles( } catch (\Exception $e) { $mappedWorkload[$mediaId]->setState(MediaProcessWorkloadStruct::ERROR_STATE); $failedMedia[] = $mediaId; - $this->loggingService->addLogEntry(new ExceptionRunLog( - $mappedWorkload[$mediaId]->getRunId(), - DefaultEntities::MEDIA, - $e, - $mediaId - )); + + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withEntityName(MediaDefinition::ENTITY_NAME) + ->withSourceData([ + 'media_id' => $mediaId, + 'source_path' => $sourcePath, + 'media' => $mediaFile, + ]) + ->withExceptionMessage($e->getMessage()) + ->withExceptionTrace($e->getTrace()) + ->withEntityId($mediaId) + ->build(ExceptionRunLog::class) + ); } \unlink($filePath); } else { $mappedWorkload[$mediaId]->setState(MediaProcessWorkloadStruct::ERROR_STATE); - $this->loggingService->addLogEntry(new CannotGetFileRunLog( - $mappedWorkload[$mediaId]->getRunId(), - DefaultEntities::MEDIA, - $mediaId, - $sourcePath - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withEntityName(MediaDefinition::ENTITY_NAME) + ->withSourceData([ + 'media_id' => $mediaId, + 'source_path' => $sourcePath, + 'media' => $mediaFile, + ]) + ->withEntityId($mediaId) + ->build(CannotGetFileRunLog::class) + ); $failedMedia[] = $mediaId; } } @@ -207,6 +234,7 @@ private function copyMediaFiles( * @param list $failedMedia */ private function persistFileToMedia( + MigrationContextInterface $migrationContext, string $filePath, array $media, int $fileSize, @@ -217,14 +245,22 @@ private function persistFileToMedia( ): void { $mediaId = $media['media_id']; $mimeType = \mime_content_type($filePath); + if ($mimeType === false) { $failedMedia[] = $mediaId; $mappedWorkload[$mediaId]->setState(MediaProcessWorkloadStruct::ERROR_STATE); - $this->loggingService->addLogEntry(new MimeTypeErrorLog( - $mappedWorkload[$mediaId]->getRunId(), - DefaultEntities::MEDIA, - $mediaId - )); + + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withEntityName(MediaDefinition::ENTITY_NAME) + ->withSourceData([ + 'media_id' => $mediaId, + 'file_path' => $filePath, + 'media' => $media, + ]) + ->withEntityId($mediaId) + ->build(MimeTypeErrorLog::class) + ); return; } diff --git a/src/Profile/Shopware/Media/LocalOrderDocumentProcessor.php b/src/Profile/Shopware/Media/LocalOrderDocumentProcessor.php index 5c9cf2ab6..cea0b1fc1 100644 --- a/src/Profile/Shopware/Media/LocalOrderDocumentProcessor.php +++ b/src/Profile/Shopware/Media/LocalOrderDocumentProcessor.php @@ -8,13 +8,14 @@ namespace SwagMigrationAssistant\Profile\Shopware\Media; use Doctrine\DBAL\Connection; +use Shopware\Core\Content\Media\MediaDefinition; use Shopware\Core\Content\Media\MediaException; use Shopware\Core\Content\Media\MediaService; use Shopware\Core\Framework\Context; use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository; use Shopware\Core\Framework\Log\Package; use Shopware\Core\Framework\Uuid\Uuid; -use SwagMigrationAssistant\Migration\DataSelection\DefaultEntities; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogBuilder; use SwagMigrationAssistant\Migration\Logging\Log\CannotGetFileRunLog; use SwagMigrationAssistant\Migration\Logging\Log\ExceptionRunLog; use SwagMigrationAssistant\Migration\Logging\LoggingServiceInterface; @@ -66,12 +67,7 @@ public function process( private function getInstallationRoot(MigrationContextInterface $migrationContext): string { - $connection = $migrationContext->getConnection(); - if ($connection === null) { - return ''; - } - - $credentials = $connection->getCredentialFields(); + $credentials = $migrationContext->getConnection()->getCredentialFields(); if ($credentials === null) { return ''; @@ -101,12 +97,19 @@ private function copyMediaFiles( if (!\is_file($sourcePath)) { $mappedWorkload[$mediaId]->setState(MediaProcessWorkloadStruct::ERROR_STATE); - $this->loggingService->addLogEntry(new CannotGetFileRunLog( - $mappedWorkload[$mediaId]->getRunId(), - DefaultEntities::ORDER_DOCUMENT, - $mediaId, - $sourcePath - )); + + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withEntityName(MediaDefinition::ENTITY_NAME) + ->withSourceData([ + 'media_id' => $mediaId, + 'source_path' => $sourcePath, + 'media' => $mappedWorkload[$mediaId], + ]) + ->withEntityId($mediaId) + ->build(CannotGetFileRunLog::class) + ); + $processedMedia[] = $mediaId; $failedMedia[] = $mediaId; @@ -124,12 +127,18 @@ private function copyMediaFiles( $mappedWorkload[$mediaId]->setState(MediaProcessWorkloadStruct::ERROR_STATE); - $this->loggingService->addLogEntry(new ExceptionRunLog( - $mappedWorkload[$mediaId]->getRunId(), - DefaultEntities::ORDER_DOCUMENT, - $e, - $mediaId - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withExceptionMessage($e->getMessage()) + ->withExceptionTrace($e->getTrace()) + ->withSourceData([ + 'media_id' => $mediaId, + 'source_path' => $sourcePath, + 'media' => $mappedWorkload[$mediaId], + ]) + ->withEntityId($mediaId) + ->build(ExceptionRunLog::class) + ); } } diff --git a/src/Profile/Shopware/Media/LocalProductDownloadProcessor.php b/src/Profile/Shopware/Media/LocalProductDownloadProcessor.php index 9f65904f3..820ef8fc4 100644 --- a/src/Profile/Shopware/Media/LocalProductDownloadProcessor.php +++ b/src/Profile/Shopware/Media/LocalProductDownloadProcessor.php @@ -8,6 +8,7 @@ namespace SwagMigrationAssistant\Profile\Shopware\Media; use Doctrine\DBAL\Connection; +use Shopware\Core\Content\Media\MediaDefinition; use Shopware\Core\Content\Media\MediaException; use Shopware\Core\Content\Media\MediaService; use Shopware\Core\Framework\Context; @@ -15,7 +16,7 @@ use Shopware\Core\Framework\Log\Package; use Shopware\Core\Framework\Uuid\Uuid; use SwagMigrationAssistant\Exception\MigrationException; -use SwagMigrationAssistant\Migration\DataSelection\DefaultEntities; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogBuilder; use SwagMigrationAssistant\Migration\Logging\Log\CannotGetFileRunLog; use SwagMigrationAssistant\Migration\Logging\Log\ExceptionRunLog; use SwagMigrationAssistant\Migration\Logging\LoggingServiceInterface; @@ -71,12 +72,7 @@ public function process( private function getInstallationRoot(MigrationContextInterface $migrationContext): string { - $connection = $migrationContext->getConnection(); - if ($connection === null) { - return ''; - } - - $credentials = $connection->getCredentialFields(); + $credentials = $migrationContext->getConnection()->getCredentialFields(); if ($credentials === null) { return ''; @@ -106,12 +102,17 @@ private function copyMediaFiles( if (!\is_file($sourcePath)) { $mappedWorkload[$mediaId]->setState(MediaProcessWorkloadStruct::ERROR_STATE); - $this->loggingService->addLogEntry(new CannotGetFileRunLog( - $mappedWorkload[$mediaId]->getRunId(), - DefaultEntities::PRODUCT_DOWNLOAD, - $mediaId, - $sourcePath - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withEntityName(MediaDefinition::ENTITY_NAME) + ->withSourceData([ + 'media_id' => $mediaId, + 'source_path' => $sourcePath, + 'media' => $mappedWorkload[$mediaId], + ]) + ->withEntityId($mediaId) + ->build(CannotGetFileRunLog::class) + ); $processedMedia[] = $mediaId; $failedMedia[] = $mediaId; @@ -129,12 +130,19 @@ private function copyMediaFiles( $mappedWorkload[$mediaId]->setState(MediaProcessWorkloadStruct::ERROR_STATE); - $this->loggingService->addLogEntry(new ExceptionRunLog( - $mappedWorkload[$mediaId]->getRunId(), - DefaultEntities::PRODUCT_DOWNLOAD, - $e, - $mediaId - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withEntityName(MediaDefinition::ENTITY_NAME) + ->withSourceData([ + 'media_id' => $mediaId, + 'source_path' => $sourcePath, + 'media' => $mappedWorkload[$mediaId], + ]) + ->withExceptionMessage($e->getMessage()) + ->withExceptionTrace($e->getTrace()) + ->withEntityId($mediaId) + ->build(ExceptionRunLog::class) + ); } } diff --git a/src/Profile/Shopware/Media/Strategy/Md5StrategyResolver.php b/src/Profile/Shopware/Media/Strategy/Md5StrategyResolver.php index 0086edc00..89247a472 100644 --- a/src/Profile/Shopware/Media/Strategy/Md5StrategyResolver.php +++ b/src/Profile/Shopware/Media/Strategy/Md5StrategyResolver.php @@ -8,6 +8,7 @@ namespace SwagMigrationAssistant\Profile\Shopware\Media\Strategy; use Shopware\Core\Framework\Log\Package; +use Shopware\Core\Framework\Util\Hasher; use SwagMigrationAssistant\Migration\MigrationContextInterface; #[Package('fundamentals@after-sales')] @@ -24,12 +25,7 @@ public function supports(string $path, MigrationContextInterface $migrationConte public function resolve(string $path, MigrationContextInterface $migrationContext): string { - $connection = $migrationContext->getConnection(); - if ($connection === null) { - return ''; - } - - $credentials = $connection->getCredentialFields(); + $credentials = $migrationContext->getConnection()->getCredentialFields(); if ($credentials === null) { return ''; @@ -45,7 +41,7 @@ public function resolve(string $path, MigrationContextInterface $migrationContex $path = \ltrim($path, '/'); $pathElements = \explode('/', $path); $pathInfo = \pathinfo($path); - $md5hash = \md5($path); + $md5hash = Hasher::hash($path, 'md5'); if (empty($pathInfo['extension'])) { return ''; diff --git a/src/Profile/Shopware/Media/Strategy/PlainStrategyResolver.php b/src/Profile/Shopware/Media/Strategy/PlainStrategyResolver.php index 16381b1e8..31b97845b 100644 --- a/src/Profile/Shopware/Media/Strategy/PlainStrategyResolver.php +++ b/src/Profile/Shopware/Media/Strategy/PlainStrategyResolver.php @@ -20,12 +20,7 @@ public function supports(string $path, MigrationContextInterface $migrationConte public function resolve(string $path, MigrationContextInterface $migrationContext): string { - $connection = $migrationContext->getConnection(); - if ($connection === null) { - return ''; - } - - $credentials = $connection->getCredentialFields(); + $credentials = $migrationContext->getConnection()->getCredentialFields(); if ($credentials === null) { return ''; diff --git a/src/Profile/Shopware/Premapping/DefaultShippingAvailabilityRuleReader.php b/src/Profile/Shopware/Premapping/DefaultShippingAvailabilityRuleReader.php index ee326b4a5..59844bd50 100644 --- a/src/Profile/Shopware/Premapping/DefaultShippingAvailabilityRuleReader.php +++ b/src/Profile/Shopware/Premapping/DefaultShippingAvailabilityRuleReader.php @@ -63,12 +63,7 @@ public function getPremapping(Context $context, MigrationContextInterface $migra protected function fillConnectionPremappingValue(MigrationContextInterface $migrationContext): void { - $connection = $migrationContext->getConnection(); - if ($connection === null) { - return; - } - - $mappingArray = $connection->getPremapping(); + $mappingArray = $migrationContext->getConnection()->getPremapping(); if ($mappingArray === null) { return; diff --git a/src/Profile/Shopware/Premapping/DeliveryTimeReader.php b/src/Profile/Shopware/Premapping/DeliveryTimeReader.php index fcae802c6..735fa78e8 100644 --- a/src/Profile/Shopware/Premapping/DeliveryTimeReader.php +++ b/src/Profile/Shopware/Premapping/DeliveryTimeReader.php @@ -63,12 +63,7 @@ public function getPremapping(Context $context, MigrationContextInterface $migra protected function fillConnectionPremappingValue(MigrationContextInterface $migrationContext): void { - $connection = $migrationContext->getConnection(); - if ($connection === null) { - return; - } - - $mappingArray = $connection->getPremapping(); + $mappingArray = $migrationContext->getConnection()->getPremapping(); if ($mappingArray === null) { return; diff --git a/src/Profile/Shopware/Premapping/NewsletterRecipientStatusReader.php b/src/Profile/Shopware/Premapping/NewsletterRecipientStatusReader.php index 8c758576f..bac7f4f8f 100644 --- a/src/Profile/Shopware/Premapping/NewsletterRecipientStatusReader.php +++ b/src/Profile/Shopware/Premapping/NewsletterRecipientStatusReader.php @@ -47,12 +47,7 @@ public function getPremapping(Context $context, MigrationContextInterface $migra protected function fillConnectionPremappingValue(MigrationContextInterface $migrationContext): void { - $connection = $migrationContext->getConnection(); - if ($connection === null) { - return; - } - - $mappingArray = $connection->getPremapping(); + $mappingArray = $migrationContext->getConnection()->getPremapping(); if ($mappingArray === null) { return; diff --git a/src/Profile/Shopware/Premapping/TransactionStateReader.php b/src/Profile/Shopware/Premapping/TransactionStateReader.php index 75d84ed6f..0b33d3981 100644 --- a/src/Profile/Shopware/Premapping/TransactionStateReader.php +++ b/src/Profile/Shopware/Premapping/TransactionStateReader.php @@ -167,6 +167,7 @@ private function setPreselection(array $mapping): void private function getPreselectionValue(string $sourceId): ?string { $preselectionValue = null; + switch ((int) $sourceId) { case 9: // partially_invoiced $preselectionValue = $this->preselectionDictionary[OrderTransactionStates::STATE_OPEN] ?? null; diff --git a/src/Profile/Shopware54/Shopware54Profile.php b/src/Profile/Shopware54/Shopware54Profile.php index 7cee38651..9a182fc60 100644 --- a/src/Profile/Shopware54/Shopware54Profile.php +++ b/src/Profile/Shopware54/Shopware54Profile.php @@ -21,7 +21,7 @@ class Shopware54Profile implements ShopwareProfileInterface final public const AUTHOR_NAME = 'shopware AG'; - final public const ICON_PATH = '/swagmigrationassistant/static/img/migration-assistant-plugin.svg'; + final public const ICON_PATH = '/swagmigrationassistant/administration/static/img/migration-assistant-plugin.svg'; public function getName(): string { diff --git a/src/Profile/Shopware55/Shopware55Profile.php b/src/Profile/Shopware55/Shopware55Profile.php index 41122790f..67b867a28 100644 --- a/src/Profile/Shopware55/Shopware55Profile.php +++ b/src/Profile/Shopware55/Shopware55Profile.php @@ -21,7 +21,7 @@ class Shopware55Profile implements ShopwareProfileInterface final public const AUTHOR_NAME = 'shopware AG'; - final public const ICON_PATH = '/swagmigrationassistant/static/img/migration-assistant-plugin.svg'; + final public const ICON_PATH = '/swagmigrationassistant/administration/static/img/migration-assistant-plugin.svg'; public function getName(): string { diff --git a/src/Profile/Shopware56/Shopware56Profile.php b/src/Profile/Shopware56/Shopware56Profile.php index 8c01f0316..d95b9459d 100644 --- a/src/Profile/Shopware56/Shopware56Profile.php +++ b/src/Profile/Shopware56/Shopware56Profile.php @@ -21,7 +21,7 @@ class Shopware56Profile implements ShopwareProfileInterface final public const AUTHOR_NAME = 'shopware AG'; - final public const ICON_PATH = '/swagmigrationassistant/static/img/migration-assistant-plugin.svg'; + final public const ICON_PATH = '/swagmigrationassistant/administration/static/img/migration-assistant-plugin.svg'; public function getName(): string { diff --git a/src/Profile/Shopware57/Shopware57Profile.php b/src/Profile/Shopware57/Shopware57Profile.php index ad9f8769d..001e0e529 100644 --- a/src/Profile/Shopware57/Shopware57Profile.php +++ b/src/Profile/Shopware57/Shopware57Profile.php @@ -21,7 +21,7 @@ class Shopware57Profile implements ShopwareProfileInterface final public const AUTHOR_NAME = 'shopware AG'; - final public const ICON_PATH = '/swagmigrationassistant/static/img/migration-assistant-plugin.svg'; + final public const ICON_PATH = '/swagmigrationassistant/administration/static/img/migration-assistant-plugin.svg'; public function getName(): string { diff --git a/src/Profile/Shopware6/Converter/CategoryCmsPageAssociationConverter.php b/src/Profile/Shopware6/Converter/CategoryCmsPageAssociationConverter.php index 32a97bfe8..c0af9a249 100644 --- a/src/Profile/Shopware6/Converter/CategoryCmsPageAssociationConverter.php +++ b/src/Profile/Shopware6/Converter/CategoryCmsPageAssociationConverter.php @@ -40,10 +40,9 @@ protected function convertData(array $data): ConvertStruct $this->context ); - if ($mapping === null) { - return new ConvertStruct(null, $converted); + if ($mapping !== null) { + $converted['cmsPageId'] = $mapping['entityId']; } - $converted['cmsPageId'] = $mapping['entityUuid']; } return new ConvertStruct($converted, null, $this->mainMapping['id']); diff --git a/src/Profile/Shopware6/Converter/CmsPageConverter.php b/src/Profile/Shopware6/Converter/CmsPageConverter.php index d9dceea0f..fc63452bd 100644 --- a/src/Profile/Shopware6/Converter/CmsPageConverter.php +++ b/src/Profile/Shopware6/Converter/CmsPageConverter.php @@ -34,20 +34,18 @@ public function supports(MigrationContextInterface $migrationContext): bool && $this->getDataSetEntity($migrationContext) === CmsPageDataSet::getEntity(); } - protected function convertData(array $data): ConvertStruct + protected function convertData(array $data): ?ConvertStruct { - $converted = $data; - // handle locked default layouts - if (isset($converted['locked']) && $converted['locked'] === true) { + if (isset($data['locked']) && $data['locked'] === true) { $cmsPageMapping = $this->mappingService->getMapping($this->connectionId, DefaultEntities::CMS_PAGE, $data['id'], $this->context); if ($cmsPageMapping !== null) { - return new ConvertStruct(null, $data, $cmsPageMapping['id']); + return null; } $cmpPageUuid = $this->cmsPageLookup->getLockedByNamesAndType( - \array_column($converted['translations'], 'name'), - $converted['type'], + \array_column($data['translations'], 'name'), + $data['type'], $this->context ); @@ -60,9 +58,11 @@ protected function convertData(array $data): ConvertStruct $cmpPageUuid, ); - return new ConvertStruct(null, $data); + return null; } + $converted = $data; + $this->updateTranslations($converted); $this->mainMapping = $this->getOrCreateMappingMainCompleteFacade( DefaultEntities::CMS_PAGE, diff --git a/src/Profile/Shopware6/Converter/CustomerWishlistConverter.php b/src/Profile/Shopware6/Converter/CustomerWishlistConverter.php index 38df224eb..9a65a772d 100644 --- a/src/Profile/Shopware6/Converter/CustomerWishlistConverter.php +++ b/src/Profile/Shopware6/Converter/CustomerWishlistConverter.php @@ -35,12 +35,12 @@ protected function convertData(array $data): ConvertStruct $customerMapping = $this->getMappingIdFacade(DefaultEntities::CUSTOMER, $converted['customerId']); if ($customerMapping === null) { - return new ConvertStruct(null, $data); + $converted['customerId'] = null; } $salesChannelMapping = $this->getMappingIdFacade(DefaultEntities::SALES_CHANNEL, $converted['salesChannelId']); if ($salesChannelMapping === null) { - return new ConvertStruct(null, $data); + $converted['salesChannelId'] = null; } // products association could be empty and thus this array key might not be set diff --git a/src/Profile/Shopware6/Converter/DocumentBaseConfigConverter.php b/src/Profile/Shopware6/Converter/DocumentBaseConfigConverter.php index 43bc1a46d..9ce720233 100644 --- a/src/Profile/Shopware6/Converter/DocumentBaseConfigConverter.php +++ b/src/Profile/Shopware6/Converter/DocumentBaseConfigConverter.php @@ -17,7 +17,6 @@ use SwagMigrationAssistant\Migration\Media\MediaFileServiceInterface; use SwagMigrationAssistant\Migration\MigrationContextInterface; use SwagMigrationAssistant\Profile\Shopware6\DataSelection\DataSet\DocumentBaseConfigDataSet; -use SwagMigrationAssistant\Profile\Shopware6\Logging\Log\UnsupportedDocumentTypeLog; use SwagMigrationAssistant\Profile\Shopware6\Shopware6MajorProfile; #[Package('fundamentals@after-sales')] @@ -56,18 +55,15 @@ protected function convertData(array $data): ConvertStruct $converted = $data; $converted['documentTypeId'] = $this->documentTypeLookup->get($converted['documentType']['technicalName'], $this->context); - if ($converted['documentTypeId'] === null) { - $this->loggingService->addLogEntry(new UnsupportedDocumentTypeLog($this->runId, DefaultEntities::ORDER_DOCUMENT_BASE_CONFIG, $data['id'], $data['documentType']['technicalName'])); - - return new ConvertStruct(null, $data, $converted['id'] ?? null); - } - unset($converted['documentType']); - - if ($data['global']) { - $converted['id'] = $this->globalDocumentBaseConfigLookup->get($converted['documentTypeId'], $this->context); - if ($converted['id'] === null) { - $converted['id'] = $data['id']; + if ($converted['documentTypeId'] !== null) { + if ($data['global']) { + $converted['id'] = $this->globalDocumentBaseConfigLookup->get($converted['documentTypeId'], $this->context); + if ($converted['id'] === null) { + $converted['id'] = $data['id']; + } } + + unset($converted['documentType']); } $this->mainMapping = $this->getOrCreateMappingMainCompleteFacade( diff --git a/src/Profile/Shopware6/Converter/DocumentConverter.php b/src/Profile/Shopware6/Converter/DocumentConverter.php index 605c8279e..9885b3bc4 100644 --- a/src/Profile/Shopware6/Converter/DocumentConverter.php +++ b/src/Profile/Shopware6/Converter/DocumentConverter.php @@ -16,7 +16,6 @@ use SwagMigrationAssistant\Migration\Media\MediaFileServiceInterface; use SwagMigrationAssistant\Migration\MigrationContextInterface; use SwagMigrationAssistant\Profile\Shopware6\DataSelection\DataSet\DocumentDataSet; -use SwagMigrationAssistant\Profile\Shopware6\Logging\Log\UnsupportedDocumentTypeLog; use SwagMigrationAssistant\Profile\Shopware6\Shopware6MajorProfile; #[Package('fundamentals@after-sales')] @@ -62,15 +61,12 @@ protected function convertData(array $data): ConvertStruct ); $converted['documentTypeId'] = $this->documentTypeLookup->get($converted['documentType']['technicalName'], $this->context); - if ($converted['documentTypeId'] === null) { - $this->loggingService->addLogEntry(new UnsupportedDocumentTypeLog($this->runId, DefaultEntities::ORDER_DOCUMENT, $data['id'], $data['documentType']['technicalName'])); - - return new ConvertStruct(null, $data, $this->mainMapping['id'] ?? null); - } - unset($converted['documentType']); + if ($converted['documentTypeId'] !== null) { + if (isset($converted['config']['documentTypeId'])) { + $converted['config']['documentTypeId'] = $converted['documentTypeId']; + } - if (isset($converted['config']['documentTypeId'])) { - $converted['config']['documentTypeId'] = $converted['documentTypeId']; + unset($converted['documentType']); } if (isset($converted['documentMediaFile'])) { diff --git a/src/Profile/Shopware6/Converter/MailTemplateConverter.php b/src/Profile/Shopware6/Converter/MailTemplateConverter.php index f09fbc19e..4aaa75c19 100644 --- a/src/Profile/Shopware6/Converter/MailTemplateConverter.php +++ b/src/Profile/Shopware6/Converter/MailTemplateConverter.php @@ -16,7 +16,6 @@ use SwagMigrationAssistant\Migration\Mapping\MappingServiceInterface; use SwagMigrationAssistant\Migration\Media\MediaFileServiceInterface; use SwagMigrationAssistant\Migration\MigrationContextInterface; -use SwagMigrationAssistant\Profile\Shopware\Logging\Log\UnsupportedMailTemplateType; use SwagMigrationAssistant\Profile\Shopware6\DataSelection\DataSet\MailTemplateDataSet; use SwagMigrationAssistant\Profile\Shopware6\Shopware6MajorProfile; @@ -60,39 +59,29 @@ protected function convertData(array $data): ConvertStruct if (isset($converted['mailTemplateType']['technicalName'])) { $mailTemplateTypeMapping = $this->mappingService->getMapping($this->connectionId, DefaultEntities::MAIL_TEMPLATE_TYPE, $data['mailTemplateTypeId'], $this->context); if ($mailTemplateTypeMapping !== null) { - $typeUuid = $mailTemplateTypeMapping['entityUuid']; + $typeUuid = $mailTemplateTypeMapping['entityId']; } else { $typeUuid = $this->mailTemplateTypeLookup->get($converted['mailTemplateType']['technicalName'], $this->context); - if ($typeUuid === null) { - $this->loggingService->addLogEntry( - new UnsupportedMailTemplateType( - $this->runId, - $data['id'], - $converted['mailTemplateType']['technicalName'] - ) + if ($typeUuid !== null) { + $this->mappingService->createMapping( + $this->connectionId, + DefaultEntities::MAIL_TEMPLATE_TYPE, + $data['mailTemplateTypeId'], + $this->checksum, + null, + $typeUuid, ); - - return new ConvertStruct(null, $data, $converted['id'] ?? null); } - - $this->mappingService->createMapping( - $this->connectionId, - DefaultEntities::MAIL_TEMPLATE_TYPE, - $data['mailTemplateTypeId'], - $this->checksum, - null, - $typeUuid, - ); } - unset($converted['mailTemplateType']); $converted['mailTemplateTypeId'] = $typeUuid; + unset($converted['mailTemplateType']); } - if ($data['systemDefault']) { + if ($data['systemDefault'] && isset($converted['mailTemplateTypeId'])) { $defaultMailTemplateMapping = $this->mappingService->getMapping($this->connectionId, DefaultEntities::MAIL_TEMPLATE, $data['id'], $this->context); if ($defaultMailTemplateMapping !== null) { - $defaultMailTemplateUuid = $defaultMailTemplateMapping['entityUuid']; + $defaultMailTemplateUuid = $defaultMailTemplateMapping['entityId']; } else { $defaultMailTemplateUuid = $this->systemDefaultMailTemplateLookup->get($converted['mailTemplateTypeId'], $this->context); } diff --git a/src/Profile/Shopware6/Converter/MediaFolderConverter.php b/src/Profile/Shopware6/Converter/MediaFolderConverter.php index 995d03c21..3bd90dc13 100644 --- a/src/Profile/Shopware6/Converter/MediaFolderConverter.php +++ b/src/Profile/Shopware6/Converter/MediaFolderConverter.php @@ -7,9 +7,11 @@ namespace SwagMigrationAssistant\Profile\Shopware6\Converter; +use Shopware\Core\Content\Media\Aggregate\MediaFolder\MediaFolderDefinition; use Shopware\Core\Framework\Log\Package; use SwagMigrationAssistant\Migration\Converter\ConvertStruct; use SwagMigrationAssistant\Migration\DataSelection\DefaultEntities; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogBuilder; use SwagMigrationAssistant\Migration\Logging\LoggingServiceInterface; use SwagMigrationAssistant\Migration\Mapping\Lookup\MediaDefaultFolderLookup; use SwagMigrationAssistant\Migration\Mapping\Lookup\MediaThumbnailSizeLookup; @@ -37,7 +39,7 @@ public function supports(MigrationContextInterface $migrationContext): bool && $this->getDataSetEntity($migrationContext) === MediaFolderDataSet::getEntity(); } - protected function convertData(array $data): ConvertStruct + protected function convertData(array $data): ?ConvertStruct { $converted = $data; @@ -51,7 +53,7 @@ protected function convertData(array $data): ConvertStruct // edge case for hidden download products media folder // this doesn't need to be migrated, just map the files into it // otherwise the code below would lead to a self-referential parentId - return new ConvertStruct(null, $data, $this->mainMapping['id'] ?? null); + return null; } if (isset($converted['defaultFolder'])) { @@ -59,12 +61,13 @@ protected function convertData(array $data): ConvertStruct if ($converted['parentId'] === null) { $this->loggingService->addLogEntry( - new UnsupportedMediaDefaultFolderLog( - $this->migrationContext->getRunUuid(), - DefaultEntities::MEDIA_FOLDER, - $data['id'], - $data['defaultFolder']['entity'] - ) + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName(MediaFolderDefinition::ENTITY_NAME) + ->withFieldName('parentId') + ->withFieldSourcePath('defaultFolder.entity') + ->withSourceData($data) + ->withConvertedData($converted) + ->build(UnsupportedMediaDefaultFolderLog::class) ); } diff --git a/src/Profile/Shopware6/Converter/NumberRangeConverter.php b/src/Profile/Shopware6/Converter/NumberRangeConverter.php index 98bc37218..1eecdb219 100644 --- a/src/Profile/Shopware6/Converter/NumberRangeConverter.php +++ b/src/Profile/Shopware6/Converter/NumberRangeConverter.php @@ -19,7 +19,6 @@ use SwagMigrationAssistant\Migration\Mapping\Lookup\NumberRangeTypeLookup; use SwagMigrationAssistant\Migration\Mapping\MappingServiceInterface; use SwagMigrationAssistant\Migration\MigrationContextInterface; -use SwagMigrationAssistant\Profile\Shopware\Logging\Log\UnsupportedNumberRangeTypeLog; use SwagMigrationAssistant\Profile\Shopware6\DataSelection\DataSet\NumberRangeDataSet; use SwagMigrationAssistant\Profile\Shopware6\Shopware6MajorProfile; @@ -52,34 +51,16 @@ protected function convertData(array $data): ConvertStruct if (isset($converted['type']['technicalName'])) { $numberRangeTypeMapping = $this->mappingService->getMapping($this->connectionId, DefaultEntities::NUMBER_RANGE_TYPE, $converted['type']['technicalName'], $this->context); if ($numberRangeTypeMapping !== null) { - $typeUuid = $numberRangeTypeMapping['entityUuid']; + $typeUuid = $numberRangeTypeMapping['entityId']; } else { $typeUuid = $this->numberRangeTypeLookup->get($converted['type']['technicalName'], $this->context); - if ($typeUuid === null) { - $this->mainMapping = $this->getOrCreateMappingMainCompleteFacade( - DefaultEntities::NUMBER_RANGE, - $data['id'], - $data['id'] - ); - - $this->loggingService->addLogEntry( - new UnsupportedNumberRangeTypeLog( - $this->runId, - DefaultEntities::NUMBER_RANGE, - $data['id'], - $converted['type']['technicalName'] - ) - ); - - return new ConvertStruct(null, $data, $this->mainMapping['id'] ?? null); - } } if ($converted['global']) { $this->checkForExistingNumberRange($converted); } - if (isset($converted['numberRangeSalesChannels'])) { + if (isset($converted['numberRangeSalesChannels']) && $typeUuid !== null) { foreach ($converted['numberRangeSalesChannels'] as &$numberRangeSalesChannel) { $numberRangeSalesChannel['numberRangeTypeId'] = $typeUuid; } diff --git a/src/Profile/Shopware6/Converter/ProductConverter.php b/src/Profile/Shopware6/Converter/ProductConverter.php index aff6ef54b..b9ba70600 100644 --- a/src/Profile/Shopware6/Converter/ProductConverter.php +++ b/src/Profile/Shopware6/Converter/ProductConverter.php @@ -139,6 +139,10 @@ protected function convertData(array $data): ConvertStruct if (isset($converted['configuratorSettings'])) { foreach ($converted['configuratorSettings'] as &$setting) { + if (!\is_array($setting)) { + continue; + } + if (isset($setting['price'])) { $this->updateAssociationIds( $setting['price'], @@ -147,7 +151,6 @@ protected function convertData(array $data): ConvertStruct DefaultEntities::PRODUCT ); - /** @phpstan-ignore-next-line */ $this->checkDefaultCurrency($setting, 'price'); } @@ -209,6 +212,9 @@ protected function convertData(array $data): ConvertStruct return new ConvertStruct($converted, null, $this->mainMapping['id'] ?? null); } + /** + * @param array $source + */ private function checkDefaultCurrency(array &$source, string $key): void { // If the default currency of source and destination is identically, there is no need to add a default price diff --git a/src/Profile/Shopware6/Converter/ProductSortingConverter.php b/src/Profile/Shopware6/Converter/ProductSortingConverter.php index 459b285f4..024b3a607 100644 --- a/src/Profile/Shopware6/Converter/ProductSortingConverter.php +++ b/src/Profile/Shopware6/Converter/ProductSortingConverter.php @@ -34,7 +34,7 @@ public function supports(MigrationContextInterface $migrationContext): bool && $this->getDataSetEntity($migrationContext) === ProductSortingDataSet::getEntity(); } - protected function convertData(array $data): ConvertStruct + protected function convertData(array $data): ?ConvertStruct { $converted = $data; $productSortingUuid = $this->productSortingLookup->get($data['key'], $this->context); @@ -50,7 +50,7 @@ protected function convertData(array $data): ConvertStruct ); if ($this->productSortingLookup->getIsLocked($data['key'], $this->context)) { - return new ConvertStruct(null, $data, $this->mainMapping['id'] ?? null); + return null; } $this->updateAssociationIds( diff --git a/src/Profile/Shopware6/Converter/SalesChannelConverter.php b/src/Profile/Shopware6/Converter/SalesChannelConverter.php index 6bac57c34..cfe101ee8 100644 --- a/src/Profile/Shopware6/Converter/SalesChannelConverter.php +++ b/src/Profile/Shopware6/Converter/SalesChannelConverter.php @@ -132,7 +132,6 @@ protected function convertData(array $data): ConvertStruct } unset( - // ToDo implement if these associations are migrated $converted['mailHeaderFooterId'] ); diff --git a/src/Profile/Shopware6/Converter/SalutationConverter.php b/src/Profile/Shopware6/Converter/SalutationConverter.php index dd0414066..ed362c360 100644 --- a/src/Profile/Shopware6/Converter/SalutationConverter.php +++ b/src/Profile/Shopware6/Converter/SalutationConverter.php @@ -40,7 +40,7 @@ protected function convertData(array $data): ConvertStruct $salutationMapping = $this->mappingService->getMapping($this->connectionId, DefaultEntities::SALUTATION, $data['id'], $this->context); if ($salutationMapping !== null) { - $salutationUuid = $salutationMapping['entityUuid']; + $salutationUuid = $salutationMapping['entityId']; } else { $salutationUuid = $this->salutationLookup->get($data['salutationKey'], $this->context); } diff --git a/src/Profile/Shopware6/Converter/SeoUrlConverter.php b/src/Profile/Shopware6/Converter/SeoUrlConverter.php index 06c2224a0..c35c6c246 100644 --- a/src/Profile/Shopware6/Converter/SeoUrlConverter.php +++ b/src/Profile/Shopware6/Converter/SeoUrlConverter.php @@ -33,34 +33,37 @@ public function supports(MigrationContextInterface $migrationContext): bool && $this->getDataSetEntity($migrationContext) === SeoUrlDataSet::getEntity(); } - protected function convertData(array $data): ConvertStruct + protected function convertData(array $data): ?ConvertStruct { if (isset($data['isModified']) && $data['isModified'] === false) { - return new ConvertStruct(null, $data); + return null; } $converted = $data; if (isset($converted['foreignKey'])) { + $relatedEntity = null; if ($converted['routeName'] === self::CATEGORY_ROUTE_NAME) { $relatedEntity = DefaultEntities::CATEGORY; } elseif ($converted['routeName'] === self::PRODUCT_ROUTE_NAME) { $relatedEntity = DefaultEntities::PRODUCT; - } else { - return new ConvertStruct(null, $converted); } - $converted['foreignKey'] = $this->getMappingIdFacade( - $relatedEntity, - $converted['foreignKey'] - ); + if ($relatedEntity !== null) { + $converted['foreignKey'] = $this->getMappingIdFacade( + $relatedEntity, + $converted['foreignKey'] + ); + } } - $this->mainMapping = $this->getOrCreateMappingMainCompleteFacade( - DefaultEntities::SEO_URL, - $data['id'], - $converted['id'] - ); + if (isset($data['id']) && isset($converted['id'])) { + $this->mainMapping = $this->getOrCreateMappingMainCompleteFacade( + DefaultEntities::SEO_URL, + $data['id'], + $converted['id'] + ); + } if (isset($converted['salesChannelId'])) { $converted['salesChannelId'] = $this->getMappingIdFacade( diff --git a/src/Profile/Shopware6/Converter/ShopwareConverter.php b/src/Profile/Shopware6/Converter/ShopwareConverter.php index d18af65cb..c9614992a 100644 --- a/src/Profile/Shopware6/Converter/ShopwareConverter.php +++ b/src/Profile/Shopware6/Converter/ShopwareConverter.php @@ -12,6 +12,7 @@ use SwagMigrationAssistant\Migration\Converter\Converter; use SwagMigrationAssistant\Migration\Converter\ConvertStruct; use SwagMigrationAssistant\Migration\Logging\Log\AssociationRequiredMissingLog; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogBuilder; use SwagMigrationAssistant\Migration\Logging\LoggingServiceInterface; use SwagMigrationAssistant\Migration\Mapping\MappingServiceInterface; use SwagMigrationAssistant\Migration\MigrationContextInterface; @@ -41,16 +42,13 @@ public function getSourceIdentifier(array $data): string return $data['id']; } - public function convert(array $data, Context $context, MigrationContextInterface $migrationContext): ConvertStruct + public function convert(array $data, Context $context, MigrationContextInterface $migrationContext): ?ConvertStruct { $this->context = $context; $this->migrationContext = $migrationContext; $connection = $migrationContext->getConnection(); - $this->connectionId = ''; - if ($connection !== null) { - $this->connectionId = $connection->getId(); - } + $this->connectionId = $connection->getId(); $this->runId = $this->migrationContext->getRunUuid(); @@ -67,7 +65,7 @@ public function convert(array $data, Context $context, MigrationContextInterface /** * @param array $data */ - abstract protected function convertData(array $data): ConvertStruct; + abstract protected function convertData(array $data): ?ConvertStruct; protected function getMappingIdFacade(string $entityName, string $oldIdentifier): ?string { @@ -84,7 +82,7 @@ protected function getMappingIdFacade(string $entityName, string $oldIdentifier) $this->mappingIds[] = $mapping['id']; - return $mapping['entityUuid']; + return $mapping['entityId']; } protected function getOrCreateMappingIdFacade( @@ -104,11 +102,11 @@ protected function getOrCreateMappingIdFacade( $this->mappingIds[] = $mapping['id']; - return $mapping['entityUuid']; + return $mapping['entityId']; } /** - * @return array{id: string, connectionId: string, oldIdentifier: ?string, entityUuid: ?string, entityValue: ?string, checksum: ?string, additionalData: ?array} + * @return array{id: string, connectionId: string, oldIdentifier: ?string, entityId: ?string, entityValue: ?string, checksum: ?string, additionalData: ?array} */ protected function getOrCreateMappingMainCompleteFacade( string $entityName, @@ -147,12 +145,12 @@ protected function updateAssociationIds(array &$associationArray, string $entity if (empty($newAssociationId)) { if ($logMissing) { - $this->loggingService->addLogEntry(new AssociationRequiredMissingLog( - $this->runId, - $entity, - $oldAssociationId, - $sourceEntity - )); + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName($entity) + ->withConvertedData($association) + ->build(AssociationRequiredMissingLog::class) + ); } if ($unsetMissing) { diff --git a/src/Profile/Shopware6/Converter/TaxRuleConverter.php b/src/Profile/Shopware6/Converter/TaxRuleConverter.php index 7cc981e21..e63df5d88 100644 --- a/src/Profile/Shopware6/Converter/TaxRuleConverter.php +++ b/src/Profile/Shopware6/Converter/TaxRuleConverter.php @@ -44,19 +44,17 @@ protected function convertData(array $data): ConvertStruct DefaultEntities::TAX, $converted['taxId'] ); - if ($taxId === null) { - return new ConvertStruct(null, $converted); + if ($taxId !== null) { + $converted['taxId'] = $taxId; } - $converted['taxId'] = $taxId; $countryId = $this->getMappingIdFacade( DefaultEntities::COUNTRY, $converted['countryId'] ); - if ($countryId === null) { - return new ConvertStruct(null, $converted); + if ($countryId !== null) { + $converted['countryId'] = $countryId; } - $converted['countryId'] = $countryId; $taxRuleTypeMapping = $this->mappingService->getMapping( $this->connectionId, @@ -66,7 +64,7 @@ protected function convertData(array $data): ConvertStruct ); if ($taxRuleTypeMapping) { - $taxRuleTypeUuid = $taxRuleTypeMapping['entityUuid']; + $taxRuleTypeUuid = $taxRuleTypeMapping['entityId']; } else { $taxRuleTypeUuid = $this->taxRuleTypeLookup->get( $converted['type']['technicalName'] ?? '', @@ -84,11 +82,10 @@ protected function convertData(array $data): ConvertStruct } // new types can not be created due to write protection on technical name - if ($taxRuleTypeUuid === null) { - return new ConvertStruct(null, $converted); + if ($taxRuleTypeUuid !== null) { + $converted['taxRuleTypeId'] = $taxRuleTypeUuid; + unset($converted['type']); } - unset($converted['type']); - $converted['taxRuleTypeId'] = $taxRuleTypeUuid; $taxRuleId = $this->taxRuleLookup->get( $converted['taxId'], diff --git a/src/Profile/Shopware6/Gateway/Api/Shopware6ApiGateway.php b/src/Profile/Shopware6/Gateway/Api/Shopware6ApiGateway.php index 57b1ee52c..030736020 100644 --- a/src/Profile/Shopware6/Gateway/Api/Shopware6ApiGateway.php +++ b/src/Profile/Shopware6/Gateway/Api/Shopware6ApiGateway.php @@ -19,6 +19,7 @@ use SwagMigrationAssistant\Migration\Gateway\Reader\EnvironmentReaderInterface; use SwagMigrationAssistant\Migration\Gateway\Reader\ReaderRegistryInterface; use SwagMigrationAssistant\Migration\MigrationContextInterface; +use SwagMigrationAssistant\Migration\Profile\ProfileInterface; use SwagMigrationAssistant\Profile\Shopware6\Gateway\ShopwareGatewayInterface; use SwagMigrationAssistant\Profile\Shopware6\Gateway\TableReaderInterface; use SwagMigrationAssistant\Profile\Shopware6\Gateway\TotalReaderInterface; @@ -54,9 +55,9 @@ public function getSnippetName(): string return 'swag-migration.wizard.pages.connectionCreate.gateways.shopwareApi'; } - public function supports(MigrationContextInterface $migrationContext): bool + public function supports(ProfileInterface $profile): bool { - return $migrationContext->getProfile() instanceof Shopware6ProfileInterface; + return $profile instanceof Shopware6ProfileInterface; } public function read(MigrationContextInterface $migrationContext): array @@ -83,20 +84,7 @@ public function readEnvironmentInformation(MigrationContextInterface $migrationC ); } - $connection = $migrationContext->getConnection(); - - if ($connection === null) { - return new EnvironmentInformation( - $profile->getSourceSystemName(), - $profile->getVersion(), - '', - [], - [], - null - ); - } - - $credentials = $connection->getCredentialFields(); + $credentials = $migrationContext->getConnection()->getCredentialFields(); if ($credentials === null) { return new EnvironmentInformation( diff --git a/src/Profile/Shopware6/Gateway/Connection/AuthClient.php b/src/Profile/Shopware6/Gateway/Connection/AuthClient.php index 281988054..4f0657632 100644 --- a/src/Profile/Shopware6/Gateway/Connection/AuthClient.php +++ b/src/Profile/Shopware6/Gateway/Connection/AuthClient.php @@ -14,6 +14,7 @@ use Shopware\Core\Framework\Context; use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository; use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Exception\MigrationException; use SwagMigrationAssistant\Migration\Connection\SwagMigrationConnectionCollection; use SwagMigrationAssistant\Migration\Gateway\HttpClientInterface; use SwagMigrationAssistant\Migration\MigrationContext; @@ -95,16 +96,10 @@ private function setupBearerTokenIfNeeded(): void private function renewBearerToken(): void { - $connection = $this->migrationContext->getConnection(); - - if ($connection === null) { - return; // TODO: throw exception - } - - $credentials = $connection->getCredentialFields(); + $credentials = $this->migrationContext->getConnection()->getCredentialFields(); if ($credentials === null) { - return; // TODO: throw exception + throw MigrationException::invalidConnectionCredentials(); } $response = $this->apiClient->post('/api/oauth/token', [ @@ -126,25 +121,20 @@ private function renewBearerToken(): void private function saveBearerToken(): void { $connection = $this->migrationContext->getConnection(); + $credentials = $connection->getCredentialFields(); - if ($connection === null) { - return; - } - - $credentialFields = $connection->getCredentialFields(); - - if ($credentialFields === null) { - return; + if ($credentials === null) { + throw MigrationException::invalidConnectionCredentials(); } $connectionUuid = $connection->getId(); - $credentialFields['bearer_token'] = $this->bearerToken; + $credentials['bearer_token'] = $this->bearerToken; - $this->context->scope(MigrationContext::SOURCE_CONTEXT, function (Context $context) use ($connectionUuid, $credentialFields): void { + $this->context->scope(MigrationContext::SOURCE_CONTEXT, function (Context $context) use ($connectionUuid, $credentials): void { $this->connectionRepository->update([ [ 'id' => $connectionUuid, - 'credentialFields' => $credentialFields, + 'credentialFields' => $credentials, ], ], $context); }); @@ -152,15 +142,7 @@ private function saveBearerToken(): void private function loadBearerToken(): void { - $connection = $this->migrationContext->getConnection(); - - if ($connection === null) { - $this->renewBearerToken(); - - return; - } - - $credentials = $connection->getCredentialFields(); + $credentials = $this->migrationContext->getConnection()->getCredentialFields(); if ($credentials === null) { $this->renewBearerToken(); diff --git a/src/Profile/Shopware6/Gateway/Connection/ConnectionFactory.php b/src/Profile/Shopware6/Gateway/Connection/ConnectionFactory.php index 4869e07a5..5c6019c1b 100644 --- a/src/Profile/Shopware6/Gateway/Connection/ConnectionFactory.php +++ b/src/Profile/Shopware6/Gateway/Connection/ConnectionFactory.php @@ -29,13 +29,7 @@ public function __construct(private readonly EntityRepository $connectionReposit public function createApiClient(MigrationContextInterface $migrationContext): ?HttpClientInterface { - $connection = $migrationContext->getConnection(); - - if ($connection === null) { - return null; - } - - $credentials = $connection->getCredentialFields(); + $credentials = $migrationContext->getConnection()->getCredentialFields(); if (empty($credentials) || !isset($credentials['endpoint'])) { return null; @@ -50,7 +44,7 @@ public function createApiClient(MigrationContextInterface $migrationContext): ?H new Client($options), $this->connectionRepository, $migrationContext, - Context::createDefaultContext() // ToDo maybe replace this with the real context from the request, because this could cause caching issues (but it will only write data to DB). + Context::createDefaultContext() ); } } diff --git a/src/Profile/Shopware6/Logging/Log/UnsupportedDocumentTypeLog.php b/src/Profile/Shopware6/Logging/Log/UnsupportedDocumentTypeLog.php index 34a79374c..00063074c 100644 --- a/src/Profile/Shopware6/Logging/Log/UnsupportedDocumentTypeLog.php +++ b/src/Profile/Shopware6/Logging/Log/UnsupportedDocumentTypeLog.php @@ -8,18 +8,14 @@ namespace SwagMigrationAssistant\Profile\Shopware6\Logging\Log; use Shopware\Core\Framework\Log\Package; -use SwagMigrationAssistant\Migration\Logging\Log\BaseRunLogEntry; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; #[Package('fundamentals@after-sales')] -class UnsupportedDocumentTypeLog extends BaseRunLogEntry +readonly class UnsupportedDocumentTypeLog extends AbstractMigrationLogEntry { - public function __construct( - string $runId, - string $entity, - string $sourceId, - private readonly string $technicalName, - ) { - parent::__construct($runId, $entity, $sourceId); + public function isUserFixable(): bool + { + return false; } public function getLevel(): string @@ -31,29 +27,4 @@ public function getCode(): string { return 'SWAG_MIGRATION__SHOPWARE_UNSUPPORTED_DOCUMENT_TYPE'; } - - public function getTitle(): string - { - return 'Unsupported document type'; - } - - public function getParameters(): array - { - return [ - 'entity' => $this->getEntity(), - 'sourceId' => $this->getSourceId(), - 'technicalName' => $this->technicalName, - ]; - } - - public function getDescription(): string - { - $args = $this->getParameters(); - - return \sprintf( - 'Document with source id "%s" could not be converted because of unsupported document type: %s.', - $args['sourceId'], - $args['technicalName'] - ); - } } diff --git a/src/Profile/Shopware6/Logging/Log/UnsupportedMediaDefaultFolderLog.php b/src/Profile/Shopware6/Logging/Log/UnsupportedMediaDefaultFolderLog.php index 7ca19bda8..122182b78 100644 --- a/src/Profile/Shopware6/Logging/Log/UnsupportedMediaDefaultFolderLog.php +++ b/src/Profile/Shopware6/Logging/Log/UnsupportedMediaDefaultFolderLog.php @@ -8,18 +8,14 @@ namespace SwagMigrationAssistant\Profile\Shopware6\Logging\Log; use Shopware\Core\Framework\Log\Package; -use SwagMigrationAssistant\Migration\Logging\Log\BaseRunLogEntry; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\AbstractMigrationLogEntry; #[Package('fundamentals@after-sales')] -class UnsupportedMediaDefaultFolderLog extends BaseRunLogEntry +readonly class UnsupportedMediaDefaultFolderLog extends AbstractMigrationLogEntry { - public function __construct( - string $runId, - string $entity, - string $sourceId, - private readonly string $defaultEntity, - ) { - parent::__construct($runId, $entity, $sourceId); + public function isUserFixable(): bool + { + return false; } public function getLevel(): string @@ -31,29 +27,4 @@ public function getCode(): string { return 'SWAG_MIGRATION__SHOPWARE_UNSUPPORTED_MEDIA_DEFAULT_FOLDER'; } - - public function getTitle(): string - { - return 'Unsupported default media folder'; - } - - public function getParameters(): array - { - return [ - 'entity' => $this->getEntity(), - 'sourceId' => $this->getSourceId(), - 'defaultEntity' => $this->defaultEntity, - ]; - } - - public function getDescription(): string - { - $args = $this->getParameters(); - - return \sprintf( - 'Media Folder with source id "%s" could not be converted because of unsupported default folder for entity: %s.', - $args['sourceId'], - $args['defaultEntity'] - ); - } } diff --git a/src/Profile/Shopware6/Media/HttpOrderDocumentGenerationService.php b/src/Profile/Shopware6/Media/HttpOrderDocumentGenerationService.php index b49ae8d10..3283a7852 100644 --- a/src/Profile/Shopware6/Media/HttpOrderDocumentGenerationService.php +++ b/src/Profile/Shopware6/Media/HttpOrderDocumentGenerationService.php @@ -20,6 +20,7 @@ use SwagMigrationAssistant\Migration\Connection\SwagMigrationConnectionEntity; use SwagMigrationAssistant\Migration\DataSelection\DefaultEntities; use SwagMigrationAssistant\Migration\Gateway\HttpClientInterface; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogBuilder; use SwagMigrationAssistant\Migration\Logging\Log\CannotGetFileRunLog; use SwagMigrationAssistant\Migration\Logging\Log\ExceptionRunLog; use SwagMigrationAssistant\Migration\Logging\LoggingServiceInterface; @@ -70,13 +71,7 @@ public function process( $mappedWorkload = []; $documentIds = []; $runId = $migrationContext->getRunUuid(); - $connection = $migrationContext->getConnection(); - - if ($connection === null) { - return $workload; - } - - $this->connection = $connection; + $this->connection = $migrationContext->getConnection(); foreach ($workload as $work) { $mappedWorkload[$work->getMediaId()] = $work; @@ -89,11 +84,14 @@ public function process( $client = $this->connectionFactory->createApiClient($migrationContext); if ($client === null) { - $this->loggingService->addLogEntry(new ExceptionRunLog( - $runId, - DefaultEntities::ORDER_DOCUMENT_GENERATED, - new \Exception('Connection to the source system could not be established') - )); + $exception = new \Exception('Connection to the source system could not be established'); + + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withExceptionMessage($exception->getMessage()) + ->withExceptionTrace($exception->getTrace()) + ->build(ExceptionRunLog::class) + ); $this->loggingService->saveLogging($context); return $workload; @@ -125,7 +123,15 @@ function (MediaProcessWorkloadStruct $work) use ($uuid) { } if ($state !== 'fulfilled') { - $this->handleFailedRequest($oldWorkload, $mappedWorkload[$uuid], $uuid, $additionalData, $failureUuids, $result['reason'] ?? null); + $this->handleFailedRequest( + $migrationContext, + $oldWorkload, + $mappedWorkload[$uuid], + $uuid, + $additionalData, + $failureUuids, + $result['reason'] ?? null + ); continue; } @@ -211,7 +217,7 @@ private function handleCompleteRequest(Context $context, array $result, string $ $mediaId = null; if ($mapping !== null) { - $mediaId = $mapping['entityUuid']; + $mediaId = $mapping['entityId']; } $context->scope(Context::SYSTEM_SCOPE, function (Context $context) use ( @@ -266,6 +272,7 @@ private function handleCompleteRequest(Context $context, array $result, string $ * @param list $failureUuids */ private function handleFailedRequest( + MigrationContextInterface $migrationContext, MediaProcessWorkloadStruct $oldWorkload, MediaProcessWorkloadStruct &$mappedWorkload, string $uuid, @@ -280,13 +287,15 @@ private function handleFailedRequest( if ($mappedWorkload->getErrorCount() > ProcessMediaHandler::MEDIA_ERROR_THRESHOLD) { $failureUuids[] = $uuid; $mappedWorkload->setState(MediaProcessWorkloadStruct::ERROR_STATE); - $this->loggingService->addLogEntry(new CannotGetFileRunLog( - $mappedWorkload->getRunId(), - DefaultEntities::ORDER_DOCUMENT, - $mappedWorkload->getMediaId(), - $mappedWorkload->getAdditionalData()['uri'], - $clientException - )); + + $this->loggingService->addLogEntry( + MigrationLogBuilder::fromMigrationContext($migrationContext) + ->withExceptionMessage($clientException?->getMessage() ?? 'Unknown error occurred') + ->withExceptionTrace($clientException?->getTrace() ?? []) + ->withSourceData($additionalData) + ->withEntityId($uuid) + ->build(CannotGetFileRunLog::class) + ); } } } diff --git a/src/Profile/Shopware6/Shopware6MajorProfile.php b/src/Profile/Shopware6/Shopware6MajorProfile.php index da28cfcfe..6684432fb 100644 --- a/src/Profile/Shopware6/Shopware6MajorProfile.php +++ b/src/Profile/Shopware6/Shopware6MajorProfile.php @@ -18,7 +18,7 @@ class Shopware6MajorProfile implements Shopware6ProfileInterface final public const AUTHOR_NAME = 'shopware AG'; - final public const ICON_PATH = '/swagmigrationassistant/static/img/migration-assistant-plugin.svg'; + final public const ICON_PATH = '/swagmigrationassistant/administration/static/img/migration-assistant-plugin.svg'; private string $supportedVersion; diff --git a/src/Resources/app/administration/.babelrc b/src/Resources/app/administration/.babelrc deleted file mode 100644 index 6acfb73e1..000000000 --- a/src/Resources/app/administration/.babelrc +++ /dev/null @@ -1,54 +0,0 @@ -{ - "presets": [ - [ - "@babel/preset-env", - { - "modules": false, - "useBuiltIns": "usage", - "corejs": 2 - } - ], - "@babel/preset-typescript" - ], - "plugins": [ - "@babel/plugin-transform-runtime", - "@babel/plugin-syntax-dynamic-import", - "@babel/plugin-syntax-import-meta", - "@babel/plugin-proposal-class-properties", - "@babel/plugin-proposal-json-strings", - [ - "@babel/plugin-proposal-decorators", - { - "legacy": true - } - ], - "@babel/plugin-proposal-function-sent", - "@babel/plugin-proposal-export-namespace-from", - "@babel/plugin-proposal-numeric-separator", - "@babel/plugin-proposal-throw-expressions" - ], - "comments": true, - "env": { - "test": { - "presets": [ - "@babel/preset-env" - ], - "plugins": [ - "@babel/plugin-syntax-dynamic-import", - "@babel/plugin-syntax-import-meta", - "@babel/plugin-proposal-class-properties", - "@babel/plugin-proposal-json-strings", - [ - "@babel/plugin-proposal-decorators", - { - "legacy": true - } - ], - "@babel/plugin-proposal-function-sent", - "@babel/plugin-proposal-export-namespace-from", - "@babel/plugin-proposal-numeric-separator", - "@babel/plugin-proposal-throw-expressions" - ] - } - } -} diff --git a/src/Resources/app/administration/.eslintignore b/src/Resources/app/administration/.eslintignore index 7ca12e18c..091ca3779 100644 --- a/src/Resources/app/administration/.eslintignore +++ b/src/Resources/app/administration/.eslintignore @@ -1,4 +1,3 @@ /node_modules /static -*.spec.vue2.js -*.fixtures.js +/.tmp diff --git a/src/Resources/app/administration/.eslintrc.js b/src/Resources/app/administration/.eslintrc.js index 81cb27b35..8efbd7199 100644 --- a/src/Resources/app/administration/.eslintrc.js +++ b/src/Resources/app/administration/.eslintrc.js @@ -1,275 +1,82 @@ /** - * @package admin + * @package fundamentals@after-sales */ - -const path = require('path'); - -const baseRules = { - // Disabled because it hides some warnings - 'file-progress/activate': 0, - // Match the max line length with the phpstorm default settings - 'max-len': ['error', 125, { ignoreRegExpLiterals: true }], - // Warn about useless path segment in import statements - 'import/no-useless-path-segments': 0, - // don't require .vue and .js extensions - 'import/extensions': ['error', 'always', { - js: 'never', - ts: 'never', - vue: 'never', - }], - 'no-console': ['error', { allow: ['warn', 'error'] }], - 'no-warning-comments': ['error', { location: 'anywhere' }], - 'inclusive-language/use-inclusive-words': 'error', - 'comma-dangle': ['error', 'always-multiline'], - 'sw-core-rules/require-position-identifier': ['error', { - components: [ - 'sw-card', - 'sw-tabs', - 'sw-extension-component-section', - ], - }], - 'sw-deprecation-rules/private-feature-declarations': 'error', - 'no-restricted-exports': 'off', - 'filename-rules/match': [2, /^(?!.*\.spec\.ts$).*(?:\.js|\.ts|\.html|\.html\.twig)$/], - 'vue/multi-word-component-names': ['error', { - ignores: ['index.html'], - }], -}; - module.exports = { root: true, - extends: [ - '@shopware-ag/eslint-config-base', - ], env: { browser: true, - 'jest/globals': true, }, - globals: { Shopware: true, - VueJS: true, - Cypress: true, - cy: true, - autoStub: true, - flushPromises: true, - wrapTestComponent: true, - resetFilters: true, }, - + extends: [ + '@shopware-ag/eslint-config-base', + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:vue/vue3-recommended', + 'prettier', + ], plugins: [ - 'jest', - 'twig-vue', + '@typescript-eslint', 'inclusive-language', 'vuejs-accessibility', 'file-progress', - 'sw-core-rules', - 'sw-deprecation-rules', - 'sw-test-rules', 'filename-rules', + 'vue', + 'html', ], - + parser: '@typescript-eslint/parser', settings: { 'import/resolver': { - node: {}, - webpack: { - config: { - // Sync with webpack.config.js - resolve: { - extensions: ['.js', '.ts', '.vue', '.json', '.less', '.twig'], - alias: { - vue$: 'vue/dist/vue.esm.js', - src: path.join(__dirname, 'src'), - module: path.join(__dirname, 'src/module'), - scss: path.join(__dirname, 'src/app/assets/scss'), - assets: path.join(__dirname, 'static'), - // Alias for externals - Shopware: path.join(__dirname, 'src/core/shopware'), - '@administration': path.join(__dirname, 'src'), - }, - }, - }, + node: { + extensions: ['.js', '.ts', '.vue', '.json', '.less', '.twig'], }, }, }, - rules: { - ...baseRules, + quotes: ['error', 'single', { avoidEscape: true }], + semi: ['error', 'always'], + 'comma-dangle': ['error', 'always-multiline'], + 'max-len': ['error', 125, { + ignoreRegExpLiterals: true, + ignoreComments: false, + ignoreStrings: true, + ignoreTemplateLiterals: true, + ignoreUrls: true, + }], + 'no-console': ['error', { allow: ['warn', 'error'] }], + 'no-debugger': 'error', + 'no-var': 'error', + 'prefer-const': 'error', + 'prefer-arrow-callback': 'error', + 'arrow-spacing': ['error', { before: true, after: true }], + 'no-empty-function': 'error', + 'import/extensions': [ + 'error', + 'ignorePackages', + { js: 'never', ts: 'never' }, + ], + 'no-void': 'off', + 'no-unused-vars': 'off', + '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }], + '@typescript-eslint/explicit-function-return-type': ['error', { allowExpressions: true }], + '@typescript-eslint/no-explicit-any': 'error', + '@typescript-eslint/consistent-type-imports': 'error', + '@typescript-eslint/ban-ts-comment': 'off', + 'implicit-arrow-linebreak': 'off', + 'function-paren-newline': 'off', }, - overrides: [ { - extends: [ - 'plugin:vue/vue3-recommended', - '@shopware-ag/eslint-config-base', - ], - files: ['**/*.js'], - excludedFiles: ['*.spec.js', '*.spec.vue3.js'], - parser: '@typescript-eslint/parser', - parserOptions: { - project: true, - tsconfigRootDir: __dirname, - }, + files: ['*.ts', '*.vue'], rules: { - ...baseRules, - '@typescript-eslint/no-floating-promises': 'warn', - 'vue/require-prop-types': 'error', - 'vue/require-default-prop': 'error', - 'vue/no-mutating-props': 'error', - 'vue/component-definition-name-casing': ['error', 'kebab-case'], - 'vue/no-boolean-default': ['error', 'default-false'], - 'vue/order-in-components': ['error', { - order: [ - 'el', - 'name', - 'parent', - 'functional', - ['template', 'render'], - 'inheritAttrs', - ['provide', 'inject'], - 'extends', - 'mixins', - 'model', - ['components', 'directives', 'filters'], - ['props', 'propsData'], - 'data', - 'metaInfo', - 'computed', - 'watch', - 'LIFECYCLE_HOOKS', - 'methods', - ['delimiters', 'comments'], - 'renderError', - ], - }], + '@typescript-eslint/explicit-module-boundary-types': 'error', }, - }, { - extends: [ - 'plugin:vue/vue3-recommended', - 'plugin:vue/essential', - 'plugin:vue/recommended', - 'eslint:recommended', - 'plugin:vuejs-accessibility/recommended', - ], - processor: 'twig-vue/twig-vue', - files: ['src/**/*.html.twig', 'test/eslint/**/*.html.twig'], - rules: { - 'vue/component-name-in-template-casing': ['error', 'kebab-case', { - registeredComponentsOnly: true, - ignores: [], - }], - 'vue/html-indent': ['error', 4, { - baseIndent: 0, - }], - 'no-multiple-empty-lines': ['error', { max: 1 }], - 'vue/attribute-hyphenation': 'error', - 'vue/multiline-html-element-content-newline': 'off', // allow more spacy templates - 'vue/html-self-closing': ['error', { - html: { - void: 'never', - normal: 'never', - component: 'always', - }, - svg: 'always', - math: 'always', - }], - 'vue/no-parsing-error': ['error', { - 'nested-comment': false, - }], - 'vue/valid-v-slot': ['error', { - allowModifiers: true, - }], - 'vue/v-slot-style': 'error', - 'vue/attributes-order': 'error', - 'vue/no-deprecated-slot-attribute': ['error'], - 'vue/no-deprecated-slot-scope-attribute': ['error'], - // eslint-disable-next-line no-warning-comments - // TODO: Make this error when all components are migrated to meteor - 'sw-deprecation-rules/no-deprecated-components': ['warn'], - 'sw-deprecation-rules/no-deprecated-component-usage': ['warn'], - 'vue/no-useless-template-attributes': 'error', - 'vue/no-lone-template': 'error', - - // Disabled rules - 'eol-last': 'off', // no newline required at the end of file - 'max-len': 'off', - 'vue/no-multiple-template-root': 'off', - 'vue/no-unused-vars': 'off', - 'vue/no-template-shadow': 'off', - 'vue/no-v-html': 'off', - 'vue/valid-template-root': 'off', - 'vue/no-v-model-argument': 'off', - 'vue/no-v-for-template-key': 'off', - 'vue/no-deprecated-filter': 'error', - - // doesn't play nicely with our twig blocks - 'vue/html-closing-bracket-newline': 'off', - 'vue/first-attribute-linebreak': 'off', - }, - }, { - files: ['**/*.spec.js', '**/*.spec.vue3.js', '**/fixtures/*.js', 'test/**/*.js', 'test/**/*.ts'], - rules: { - 'sw-test-rules/await-async-functions': 'error', - 'max-len': 0, - 'sw-deprecation-rules/private-feature-declarations': 0, - 'jest/expect-expect': 'error', - 'jest/no-duplicate-hooks': 'error', - 'jest/no-test-return-statement': 'error', - 'jest/prefer-hooks-in-order': 'error', - 'jest/prefer-hooks-on-top': 'error', - 'jest/prefer-to-be': 'error', - 'jest/require-top-level-describe': 'error', - 'jest/prefer-to-contain': 'error', - 'jest/prefer-to-have-length': 'error', - 'jest/consistent-test-it': ['error', { fn: 'it', withinDescribe: 'it' }], - }, - extends: ['plugin:jest/recommended'], - }, { - files: ['**/snippet/*.json'], - rules: { - 'inclusive-language/use-inclusive-words': 'error', - }, - }, { - files: ['**/*.ts', '**/*.tsx'], - extends: [ - '@shopware-ag/eslint-config-base', - 'plugin:@typescript-eslint/eslint-recommended', - 'plugin:@typescript-eslint/recommended', - 'plugin:@typescript-eslint/recommended-requiring-type-checking', - ], - parser: '@typescript-eslint/parser', - parserOptions: { - tsconfigRootDir: __dirname, - project: ['./tsconfig.json'], - }, - plugins: ['@typescript-eslint'], + }, + { + files: ['*.spec.ts', '*.test.ts'], rules: { - ...baseRules, - '@typescript-eslint/ban-ts-comment': 0, - '@typescript-eslint/no-unsafe-member-access': 'error', - '@typescript-eslint/no-unsafe-call': 'error', - '@typescript-eslint/no-unsafe-assignment': 'error', - '@typescript-eslint/no-unsafe-return': 'error', - '@typescript-eslint/explicit-module-boundary-types': 0, - '@typescript-eslint/prefer-ts-expect-error': 'error', - 'no-shadow': 'off', - '@typescript-eslint/no-shadow': ['error'], - '@typescript-eslint/consistent-type-imports': ['error'], - '@typescript-eslint/no-floating-promises': 'warn', - 'import/extensions': [ - 'error', - 'ignorePackages', - { - js: 'never', - jsx: 'never', - ts: 'never', - tsx: 'never', - }, - ], - 'no-void': 'off', - // Disable the base rule as it can report incorrect errors - 'no-unused-vars': 'off', - '@typescript-eslint/no-unused-vars': 'error', + '@typescript-eslint/no-empty-function': 'off', }, }, ], diff --git a/src/Resources/app/administration/.stylelintrc b/src/Resources/app/administration/.stylelintrc new file mode 100644 index 000000000..6353db612 --- /dev/null +++ b/src/Resources/app/administration/.stylelintrc @@ -0,0 +1,41 @@ +{ + "extends": "stylelint-config-standard-scss", + "ignoreFiles": [ + "node_modules/" + ], + "rules": { + "indentation": 4, + "color-hex-case": "lower", + "no-missing-end-of-source-newline": true, + "property-no-unknown": [true, { + "severity": "warning", + "ignoreProperties": [ + "user-focus", + "user-input", + "user-modify" + ] + }], + "no-descending-specificity": null, + "max-nesting-depth": [4, { + "ignore": ["blockless-at-rules", "pseudo-classes"], + "severity": "warning" + }], + "at-rule-no-unknown": null, + "scss/at-rule-no-unknown": true, + "selector-class-pattern": null, + "color-function-notation": "legacy", + "declaration-block-no-redundant-longhand-properties": null, + "scss/no-global-function-names": null, + "property-no-vendor-prefix": null, + "custom-property-pattern": null, + "max-line-length": [ + 120, + { + "severity": "warning" + } + ], + "scss/dollar-variable-pattern": null, + "selector-id-pattern": null, + "keyframes-name-pattern": null + } +} diff --git a/src/Resources/app/administration/package-lock.json b/src/Resources/app/administration/package-lock.json index 39274afe6..e7ad527d0 100644 --- a/src/Resources/app/administration/package-lock.json +++ b/src/Resources/app/administration/package-lock.json @@ -1,8605 +1,3253 @@ { - "name": "swagmigrationassistant", - "version": "1.0.0", + "name": "swag-migration-assistant", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "swagmigrationassistant", - "version": "1.0.0", + "name": "swag-migration-assistant", "license": "MIT", "devDependencies": { - "@babel/core": "^7.24.5", - "@babel/eslint-parser": "^7.24.5", - "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/plugin-proposal-decorators": "^7.24.1", - "@babel/plugin-proposal-export-namespace-from": "^7.18.9", - "@babel/plugin-proposal-function-sent": "^7.24.1", - "@babel/plugin-proposal-json-strings": "^7.18.6", - "@babel/plugin-proposal-numeric-separator": "^7.18.6", - "@babel/plugin-proposal-throw-expressions": "^7.24.1", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-transform-runtime": "^7.24.3", - "@babel/preset-env": "^7.24.5", - "@babel/preset-typescript": "^7.24.1", - "@babel/register": "^7.23.7", - "@shopware-ag/eslint-config-base": "^2.0.0", - "@shopware-ag/stylelint-plugin-meteor": "^1.1.0", - "@typescript-eslint/eslint-plugin": "^7.9.0", - "@typescript-eslint/parser": "^7.9.0", - "babel-jest": "^29.7.0", - "babel-plugin-istanbul": "^6.1.1", - "babel-plugin-module-resolver": "^5.0.2", - "core-js": "^2.6.12", - "eslint": "^8.57.0", - "eslint-import-resolver-webpack": "^0.13.8", - "eslint-plugin-file-progress": "^1.4.0", - "eslint-plugin-filename-rules": "^1.3.1", - "eslint-plugin-html": "^8.1.1", - "eslint-plugin-inclusive-language": "^2.2.1", - "eslint-plugin-jest": "^28.5.0", - "eslint-plugin-plugin-rules": "file:../../../../../../../src/Administration/Resources/app/administration/eslint-rules/plugin-rules", - "eslint-plugin-simple-import-sort": "^12.1.0", - "eslint-plugin-sw-core-rules": "file:../../../../../../../src/Administration/Resources/app/administration/eslint-rules/core-rules", - "eslint-plugin-sw-deprecation-rules": "file:../../../../../../../src/Administration/Resources/app/administration/eslint-rules/deprecation-rules", - "eslint-plugin-sw-test-rules": "file:../../../../../../../src/Administration/Resources/app/administration/eslint-rules/test-rules", - "eslint-plugin-twig-vue": "file:../../../../../../../src/Administration/Resources/app/administration/twigVuePlugin", - "eslint-plugin-vue": "^9.26.0", - "eslint-plugin-vuejs-accessibility": "^2.3.0", - "stylelint": "^16.16.0", - "stylelint-define-config": "^16.15.0" - } - }, - "../../../../../../../src/Administration/Resources/app/administration/eslint-rules/core-rules": { - "name": "sw-core-rules", - "version": "1.0.0", - "dev": true - }, - "../../../../../../../src/Administration/Resources/app/administration/eslint-rules/deprecation-rules": { - "name": "sw-deprecation-rules", - "version": "1.0.0", - "dev": true - }, - "../../../../../../../src/Administration/Resources/app/administration/eslint-rules/plugin-rules": { - "version": "1.0.0", - "dev": true - }, - "../../../../../../../src/Administration/Resources/app/administration/eslint-rules/test-rules": { - "name": "sw-test-rules", - "version": "1.0.0", - "dev": true - }, - "../../../../../../../src/Administration/Resources/app/administration/twigVuePlugin": { - "name": "eslint-plugin-twig-vue", - "version": "0.0.0", - "dev": true, - "license": "ISC", - "dependencies": { - "requireindex": "~1.1.0" - }, - "devDependencies": { - "eslint": "^7.1.0", - "mocha": "^7.2.0" - }, + "@shopware-ag/eslint-config-base": "2.0.0", + "@typescript-eslint/eslint-plugin": "8.21.0", + "@typescript-eslint/parser": "8.21.0", + "eslint": "8.57.1", + "eslint-config-prettier": "9.1.0", + "eslint-plugin-file-progress": "1.5.0", + "eslint-plugin-filename-rules": "1.3.1", + "eslint-plugin-html": "7.1.0", + "eslint-plugin-import": "2.31.0", + "eslint-plugin-inclusive-language": "2.2.1", + "eslint-plugin-vue": "9.32.0", + "eslint-plugin-vuejs-accessibility": "2.4.1", + "prettier": "3.6.2", + "prettier-plugin-multiline-arrays": "3.0.6", + "stylelint": "14.16.1", + "stylelint-config-standard": "26.0.0", + "stylelint-config-standard-scss": "5.0.0", + "stylelint-junit-formatter": "0.2.2", + "typescript": "5.7.3", + "vue": "3.5.22", + "vue-eslint-parser": "9.4.3" + } + }, + "node_modules/@augment-vir/common": { + "version": "28.2.4", + "resolved": "https://registry.npmjs.org/@augment-vir/common/-/common-28.2.4.tgz", + "integrity": "sha512-5Ib0OX7YlxAuFrG+MAoTsz6RlKMcbdMdoNGcEEKH/ezc/ZKMy/IHZ9Z/ZcCHYopZ4ocGXzVY4KUOiJ8+CXXvTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "browser-or-node": "^3.0.0", + "run-time-assertions": "^1.5.1", + "type-fest": "^4.20.1" + } + }, + "node_modules/@augment-vir/common/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" + "node": ">=16" }, - "engines": { - "node": ">=6.0.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@babel/code-frame": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", - "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.24.2", - "picocolors": "^1.0.0" + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/compat-data": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.4.tgz", - "integrity": "sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==", + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/core": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.5.tgz", - "integrity": "sha512-tVQRucExLQ02Boi4vdPp49svNGcfL2GhdTCT9aldhXgCJVAI21EtRfBettiuLUwce/7r6bFdgs6JFkcdTiFttA==", + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.2", - "@babel/generator": "^7.24.5", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.24.5", - "@babel/helpers": "^7.24.5", - "@babel/parser": "^7.24.5", - "@babel/template": "^7.24.0", - "@babel/traverse": "^7.24.5", - "@babel/types": "^7.24.5", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, + "license": "MIT", "engines": { "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/eslint-parser": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.24.5.tgz", - "integrity": "sha512-gsUcqS/fPlgAw1kOtpss7uhY6E9SFFANQ6EFX5GTvzUwaV0+sGaZWk6xq22MOdeT9wfxyokW3ceCUvOiRtZciQ==", - "dev": true, - "dependencies": { - "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", - "eslint-visitor-keys": "^2.1.0", - "semver": "^6.3.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || >=14.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.11.0", - "eslint": "^7.5.0 || ^8.0.0 || ^9.0.0" } }, - "node_modules/@babel/generator": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.5.tgz", - "integrity": "sha512-x32i4hEXvr+iI0NEoEfDKzlemF8AmtOP8CcrRaEcpzysWuoEb1KknpcvMsHKPONoKZiDuItklgWhB18xEhr9PA==", + "node_modules/@babel/parser": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.24.5", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" + "@babel/types": "^7.28.5" }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", - "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" + "bin": { + "parser": "bin/babel-parser.js" }, "engines": { - "node": ">=6.9.0" + "node": ">=6.0.0" } }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", - "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", + "node_modules/@babel/types": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.15" + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", - "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "node_modules/@csstools/selector-specificity": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz", + "integrity": "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==", "dev": true, - "dependencies": { - "@babel/compat-data": "^7.23.5", - "@babel/helper-validator-option": "^7.23.5", - "browserslist": "^4.22.2", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, + "license": "CC0-1.0", "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.5.tgz", - "integrity": "sha512-uRc4Cv8UQWnE4NXlYTIIdM7wfFkOqlFztcC/gVXDKohKoVB3OyonfelUBaJzSwpBntZ2KYGF/9S7asCHsXwW6g==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-member-expression-to-functions": "^7.24.5", - "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.24.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.24.5", - "semver": "^6.3.1" + "node": "^14 || ^16 || >=18" }, - "engines": { - "node": ">=6.9.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "postcss-selector-parser": "^6.0.10" } }, - "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", - "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "regexpu-core": "^5.3.1", - "semver": "^6.3.1" + "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": ">=6.9.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", - "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", - "dev": true, - "dependencies": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" + "funding": { + "url": "https://opencollective.com/eslint" }, "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true, + "license": "MIT", "engines": { - "node": ">=6.9.0" + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, - "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" }, "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, - "engines": { - "node": ">=6.9.0" + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.5.tgz", - "integrity": "sha512-4owRteeihKWKamtqg4JmWSsEZU445xpFRXPEwp44HbgbxdWlUV1b4Agg4lkA806Lil5XM/e+FJyS0vj5T6vmcA==", + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.24.5" - }, - "engines": { - "node": ">=6.9.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/@babel/helper-module-imports": { - "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz", - "integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==", + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { - "@babel/types": "^7.24.0" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=6.9.0" + "node": "*" } }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.5.tgz", - "integrity": "sha512-9GxeY8c2d2mdQUP1Dye0ks3VDyIMS98kt/llQ2nUId8IsWqTF0l1LkSX0/uP7l7MCDrzXS009Hyhe2gzTiGW8A==", + "node_modules/@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-module-imports": "^7.24.3", - "@babel/helper-simple-access": "^7.24.5", - "@babel/helper-split-export-declaration": "^7.24.5", - "@babel/helper-validator-identifier": "^7.24.5" - }, + "license": "MIT", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", - "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", + "node_modules/@humanwhocodes/config-array": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@babel/types": "^7.22.5" + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" }, "engines": { - "node": ">=6.9.0" + "node": ">=10.10.0" } }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.5.tgz", - "integrity": "sha512-xjNLDopRzW2o6ba0gKbkZq5YWEBaK3PCyTOY1K2P/O07LGMhMqlMXPxwN4S5/RhWuCobT8z0jrlKGlYmeR1OhQ==", + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, - "engines": { - "node": ">=6.9.0" + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", - "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-wrap-function": "^7.22.20" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "node": "*" } }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.1.tgz", - "integrity": "sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==", + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-member-expression-to-functions": "^7.23.0", - "@babel/helper-optimise-call-expression": "^7.22.5" - }, + "license": "Apache-2.0", "engines": { - "node": ">=6.9.0" + "node": ">=12.22" }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@babel/helper-simple-access": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.5.tgz", - "integrity": "sha512-uH3Hmf5q5n7n8mz7arjUlDOCbttY/DW4DYhE6FUsjKJ/oYC1kQQUvwEQWxRwUpX9qQKRXeqLwWxrqilMrf32sQ==", + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.24.5" + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" }, "engines": { - "node": ">=6.9.0" + "node": ">= 8" } }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", - "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, + "license": "MIT", "engines": { - "node": ">=6.9.0" + "node": ">= 8" } }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.5.tgz", - "integrity": "sha512-5CHncttXohrHk8GWOFCcCl4oRD9fKosWlIRgWm4ql9VYioKm52Mk2xsmoohvm7f3JoiLSM5ZgJuRaf5QZZYd3Q==", + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.24.5" + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" }, "engines": { - "node": ">=6.9.0" + "node": ">= 8" } }, - "node_modules/@babel/helper-string-parser": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz", - "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==", + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", "dev": true, - "engines": { - "node": ">=6.9.0" - } + "license": "MIT" }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz", - "integrity": "sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA==", + "node_modules/@shopware-ag/eslint-config-base": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@shopware-ag/eslint-config-base/-/eslint-config-base-2.0.0.tgz", + "integrity": "sha512-G7VOfkg9SsybDfCohUB+YRcn/yaTzxQfNLfNdmvE03BK7kh0f2edwUu64FfQKMcRzVmL8lvu/sl4oErTJsNsQA==", "dev": true, - "engines": { - "node": ">=6.9.0" + "license": "MIT", + "dependencies": { + "eslint": "^8.29.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-plugin-import": "2.26.0" } }, - "node_modules/@babel/helper-validator-option": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", - "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "node_modules/@shopware-ag/eslint-config-base/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, - "engines": { - "node": ">=6.9.0" + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/@babel/helper-wrap-function": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.24.5.tgz", - "integrity": "sha512-/xxzuNvgRl4/HLNKvnFwdhdgN3cpLxgLROeLDl83Yx0AJ1SGvq1ak0OszTOjDfiB8Vx03eJbeDWh9r+jCCWttw==", + "node_modules/@shopware-ag/eslint-config-base/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-function-name": "^7.23.0", - "@babel/template": "^7.24.0", - "@babel/types": "^7.24.5" - }, - "engines": { - "node": ">=6.9.0" + "ms": "2.0.0" } }, - "node_modules/@babel/helpers": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.5.tgz", - "integrity": "sha512-CiQmBMMpMQHwM5m01YnrM6imUG1ebgYJ+fAIW4FZe6m4qHTPaRHti+R8cggAwkdz4oXhtO4/K9JWlh+8hIfR2Q==", + "node_modules/@shopware-ag/eslint-config-base/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@babel/template": "^7.24.0", - "@babel/traverse": "^7.24.5", - "@babel/types": "^7.24.5" + "esutils": "^2.0.2" }, "engines": { - "node": ">=6.9.0" + "node": ">=0.10.0" } }, - "node_modules/@babel/highlight": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.5.tgz", - "integrity": "sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.5", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.5.tgz", - "integrity": "sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.5.tgz", - "integrity": "sha512-LdXRi1wEMTrHVR4Zc9F8OewC3vdm5h4QB6L71zy6StmYeqGi1b3ttIO8UC+BfZKcH9jdr4aI249rBkm+3+YvHw==", + "node_modules/@shopware-ag/eslint-config-base/node_modules/eslint-plugin-import": { + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", + "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.24.5" + "array-includes": "^3.1.4", + "array.prototype.flat": "^1.2.5", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.7.3", + "has": "^1.0.3", + "is-core-module": "^2.8.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.values": "^1.1.5", + "resolve": "^1.22.0", + "tsconfig-paths": "^3.14.1" }, "engines": { - "node": ">=6.9.0" + "node": ">=4" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" } }, - "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.1.tgz", - "integrity": "sha512-y4HqEnkelJIOQGd+3g1bTeKsA5c6qM7eOn7VggGVbBc0y8MLSKHacwcIE2PplNlQSj0PqS9rrXL/nkPVK+kUNg==", + "node_modules/@shopware-ag/eslint-config-base/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "node": "*" } }, - "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.1.tgz", - "integrity": "sha512-Hj791Ii4ci8HqnaKHAlLNs+zaLXb0EzSDhiAWp5VNlyvCNymYfacs64pxTxbH1znW/NcArSmwpmG9IKE/TUVVQ==", + "node_modules/@shopware-ag/eslint-config-base/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.21.0.tgz", + "integrity": "sha512-eTH+UOR4I7WbdQnG4Z48ebIA6Bgi7WO8HvFEneeYBxG8qCOYgTOFPSg6ek9ITIDvGjDQzWHcoWHCDO2biByNzA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.24.1" + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.21.0", + "@typescript-eslint/type-utils": "8.21.0", + "@typescript-eslint/utils": "8.21.0", + "@typescript-eslint/visitor-keys": "8.21.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.0.0" }, "engines": { - "node": ">=6.9.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@babel/core": "^7.13.0" + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" } }, - "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.1.tgz", - "integrity": "sha512-m9m/fXsXLiHfwdgydIFnpk+7jlVbnvlK5B2EKiPdLUb6WX654ZaaEWJUjk8TftRbZpK0XibovlLWX4KIZhV6jw==", + "node_modules/@typescript-eslint/parser": { + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.21.0.tgz", + "integrity": "sha512-Wy+/sdEH9kI3w9civgACwabHbKl+qIOu0uFZ9IMKzX3Jpv9og0ZBJrZExGrPpFAY7rWsXuxs5e7CPPP17A4eYA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.24.0" + "@typescript-eslint/scope-manager": "8.21.0", + "@typescript-eslint/types": "8.21.0", + "@typescript-eslint/typescript-estree": "8.21.0", + "@typescript-eslint/visitor-keys": "8.21.0", + "debug": "^4.3.4" }, "engines": { - "node": ">=6.9.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" } }, - "node_modules/@babel/plugin-proposal-class-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", - "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", - "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.", + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.21.0.tgz", + "integrity": "sha512-G3IBKz0/0IPfdeGRMbp+4rbjfSSdnGkXsM/pFZA8zM9t9klXDnB/YnKOBQ0GoPmoROa4bCq2NeHgJa5ydsQ4mA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@typescript-eslint/types": "8.21.0", + "@typescript-eslint/visitor-keys": "8.21.0" }, "engines": { - "node": ">=6.9.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@babel/plugin-proposal-decorators": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.24.1.tgz", - "integrity": "sha512-zPEvzFijn+hRvJuX2Vu3KbEBN39LN3f7tW3MQO2LsIs57B26KU+kUc82BdAktS1VCM6libzh45eKGI65lg0cpA==", + "node_modules/@typescript-eslint/type-utils": { + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.21.0.tgz", + "integrity": "sha512-95OsL6J2BtzoBxHicoXHxgk3z+9P3BEcQTpBKriqiYzLKnM2DeSqs+sndMKdamU8FosiadQFT3D+BSL9EKnAJQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-decorators": "^7.24.1" + "@typescript-eslint/typescript-estree": "8.21.0", + "@typescript-eslint/utils": "8.21.0", + "debug": "^4.3.4", + "ts-api-utils": "^2.0.0" }, "engines": { - "node": ">=6.9.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" } }, - "node_modules/@babel/plugin-proposal-export-namespace-from": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", - "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", - "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-export-namespace-from instead.", + "node_modules/@typescript-eslint/types": { + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.21.0.tgz", + "integrity": "sha512-PAL6LUuQwotLW2a8VsySDBwYMm129vFm4tMVlylzdoTybTHaAi0oBp7Ac6LhSrHHOdLM3efH+nAR6hAWoMF89A==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - }, + "license": "MIT", "engines": { - "node": ">=6.9.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@babel/plugin-proposal-function-sent": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-function-sent/-/plugin-proposal-function-sent-7.24.1.tgz", - "integrity": "sha512-GxHpB7jATDZWYEuYkR5jv5aiHbwkmbvk3fJP5G2Dvl7va+kewfbYxpnU1BadIHd3kXlLPQj4CKbLKoWxX4nTtA==", + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.21.0.tgz", + "integrity": "sha512-x+aeKh/AjAArSauz0GiQZsjT8ciadNMHdkUSwBB9Z6PrKc/4knM4g3UfHml6oDJmKC88a6//cdxnO/+P2LkMcg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-wrap-function": "^7.22.20", - "@babel/plugin-syntax-function-sent": "^7.24.1" + "@typescript-eslint/types": "8.21.0", + "@typescript-eslint/visitor-keys": "8.21.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.0.0" }, "engines": { - "node": ">=6.9.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "typescript": ">=4.8.4 <5.8.0" } }, - "node_modules/@babel/plugin-proposal-json-strings": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", - "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", - "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-json-strings instead.", + "node_modules/@typescript-eslint/utils": { + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.21.0.tgz", + "integrity": "sha512-xcXBfcq0Kaxgj7dwejMbFyq7IOHgpNMtVuDveK7w3ZGwG9owKzhALVwKpTF2yrZmEwl9SWdetf3fxNzJQaVuxw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-json-strings": "^7.8.3" + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.21.0", + "@typescript-eslint/types": "8.21.0", + "@typescript-eslint/typescript-estree": "8.21.0" }, "engines": { - "node": ">=6.9.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" } }, - "node_modules/@babel/plugin-proposal-numeric-separator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", - "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", - "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-numeric-separator instead.", + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.21.0.tgz", + "integrity": "sha512-BkLMNpdV6prozk8LlyK/SOoWLmUFi+ZD+pcqti9ILCbVvHGk1ui1g4jJOc2WDLaeExz2qWwojxlPce5PljcT3w==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" + "@typescript-eslint/types": "8.21.0", + "eslint-visitor-keys": "^4.2.0" }, "engines": { - "node": ">=6.9.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.21.0-placeholder-for-preset-env.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", - "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, + "license": "Apache-2.0", "engines": { - "node": ">=6.9.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@babel/plugin-proposal-throw-expressions": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-throw-expressions/-/plugin-proposal-throw-expressions-7.24.1.tgz", - "integrity": "sha512-wiae/VkKNX1WuM+wXIeAZY1cvbVKJJIf92eA23s2ufpp4w+vOlp+/4T3yfxN6nzN+hIwT15AsdwujAelIqNW+w==", + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-throw-expressions": "^7.24.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } + "license": "ISC" }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "node_modules/@vue/compiler-core": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.22.tgz", + "integrity": "sha512-jQ0pFPmZwTEiRNSb+i9Ow/I/cHv2tXYqsnHKKyCQ08irI2kdF5qmYedmF8si8mA7zepUFmJ2hqzS8CQmNOWOkQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/parser": "^7.28.4", + "@vue/shared": "3.5.22", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.1" } }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "node_modules/@vue/compiler-dom": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.22.tgz", + "integrity": "sha512-W8RknzUM1BLkypvdz10OVsGxnMAuSIZs9Wdx1vzA3mL5fNMN15rhrSCLiTm6blWeACwUwizzPVqGJgOGBEN/hA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@vue/compiler-core": "3.5.22", + "@vue/shared": "3.5.22" } }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "node_modules/@vue/compiler-sfc": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.22.tgz", + "integrity": "sha512-tbTR1zKGce4Lj+JLzFXDq36K4vcSZbJ1RBu8FxcDv1IGRz//Dh2EBqksyGVypz3kXpshIfWKGOCcqpSbyGWRJQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/parser": "^7.28.4", + "@vue/compiler-core": "3.5.22", + "@vue/compiler-dom": "3.5.22", + "@vue/compiler-ssr": "3.5.22", + "@vue/shared": "3.5.22", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.19", + "postcss": "^8.5.6", + "source-map-js": "^1.2.1" } }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "node_modules/@vue/compiler-ssr": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.22.tgz", + "integrity": "sha512-GdgyLvg4R+7T8Nk2Mlighx7XGxq/fJf9jaVofc3IL0EPesTE86cP/8DD1lT3h1JeZr2ySBvyqKQJgbS54IX1Ww==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@vue/compiler-dom": "3.5.22", + "@vue/shared": "3.5.22" } }, - "node_modules/@babel/plugin-syntax-decorators": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.24.1.tgz", - "integrity": "sha512-05RJdO/cCrtVWuAaSn1tS3bH8jbsJa/Y1uD186u6J4C/1mnHFxseeuWpsqr9anvo7TUulev7tm7GDwRV+VuhDw==", + "node_modules/@vue/reactivity": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.22.tgz", + "integrity": "sha512-f2Wux4v/Z2pqc9+4SmgZC1p73Z53fyD90NFWXiX9AKVnVBEvLFOWCEgJD3GdGnlxPZt01PSlfmLqbLYzY/Fw4A==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@vue/shared": "3.5.22" } }, - "node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "node_modules/@vue/runtime-core": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.22.tgz", + "integrity": "sha512-EHo4W/eiYeAzRTN5PCextDUZ0dMs9I8mQ2Fy+OkzvRPUYQEyK9yAjbasrMCXbLNhF7P0OUyivLjIy0yc6VrLJQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@vue/reactivity": "3.5.22", + "@vue/shared": "3.5.22" } }, - "node_modules/@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "node_modules/@vue/runtime-dom": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.22.tgz", + "integrity": "sha512-Av60jsryAkI023PlN7LsqrfPvwfxOd2yAwtReCjeuugTJTkgrksYJJstg1e12qle0NarkfhfFu1ox2D+cQotww==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@vue/reactivity": "3.5.22", + "@vue/runtime-core": "3.5.22", + "@vue/shared": "3.5.22", + "csstype": "^3.1.3" } }, - "node_modules/@babel/plugin-syntax-function-sent": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-function-sent/-/plugin-syntax-function-sent-7.24.1.tgz", - "integrity": "sha512-aVwkxqagsGCI8vtuyMI+LnZ2SWtGP4+v9T/T88j2MwKRsGYzc9FAaEzsNMu1Htu6SsHPcfwQ7uZ7pYPGrVmG+g==", + "node_modules/@vue/server-renderer": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.22.tgz", + "integrity": "sha512-gXjo+ao0oHYTSswF+a3KRHZ1WszxIqO7u6XwNHqcqb9JfyIL/pbWrrh/xLv7jeDqla9u+LK7yfZKHih1e1RKAQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" + "@vue/compiler-ssr": "3.5.22", + "@vue/shared": "3.5.22" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "vue": "3.5.22" } }, - "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.1.tgz", - "integrity": "sha512-IuwnI5XnuF189t91XbxmXeCDz3qs6iDRO7GJ++wcfgeXNs/8FmIlKcpDSXNVyuLQxlwvskmI3Ct73wUODkJBlQ==", + "node_modules/@vue/shared": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.22.tgz", + "integrity": "sha512-F4yc6palwq3TT0u+FYf0Ns4Tfl9GRFURDN2gWG7L1ecIaS/4fCIuFOjMTnCyjsu/OK6vaDKLCrGAa+KvvH+h4w==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } + "license": "MIT" }, - "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.1.tgz", - "integrity": "sha512-zhQTMH0X2nVLnb04tz+s7AMuasX8U0FnpE+nHTOhSOINjWMnopoZTxtIKsd45n4GQ/HIZLyfIpoul8e2m0DnRA==", + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "license": "MIT", + "bin": { + "acorn": "bin/acorn" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=0.4.0" } }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, + "license": "MIT", "peerDependencies": { - "@babel/core": "^7.0.0-0" + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.1.tgz", - "integrity": "sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==", + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, + "license": "MIT", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=8" } }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "color-convert": "^2.0.1" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "engines": { + "node": ">=8" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } + "license": "Python-2.0" }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" } }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "engines": { + "node": ">= 0.4" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "node_modules/array-includes": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" }, "engines": { - "node": ">=6.9.0" + "node": ">= 0.4" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@babel/plugin-syntax-throw-expressions": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-throw-expressions/-/plugin-syntax-throw-expressions-7.24.1.tgz", - "integrity": "sha512-o4dN/9/hUAC6RuX1QZDlauBG2nmSmUMk0K7/IOIFxjM8V16FS1JTHHiBWqGkkIjK4myeHucJbBHurqjtWFAdsw==", + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, + "license": "MIT", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=8" } }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "node_modules/array.prototype.findlastindex": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" }, "engines": { - "node": ">=6.9.0" + "node": ">= 0.4" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.1.tgz", - "integrity": "sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw==", + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { - "node": ">=6.9.0" + "node": ">= 0.4" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@babel/plugin-syntax-unicode-sets-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", - "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { - "node": ">=6.9.0" + "node": ">= 0.4" }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.1.tgz", - "integrity": "sha512-ngT/3NkRhsaep9ck9uj2Xhv9+xB1zShY3tM3g6om4xxCELwCDN4g4Aq5dRn48+0hasAql7s2hdBOysCfNpr4fw==", + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" }, "engines": { - "node": ">=6.9.0" + "node": ">= 0.4" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.3.tgz", - "integrity": "sha512-Qe26CMYVjpQxJ8zxM1340JFNjZaF+ISWpr1Kt/jGo+ZTUzKkfw/pphEWbRCb+lmSM6k/TOgfYLvmbHkUQ0asIg==", + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-remap-async-to-generator": "^7.22.20", - "@babel/plugin-syntax-async-generators": "^7.8.4" - }, + "license": "MIT", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=0.10.0" } }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.1.tgz", - "integrity": "sha512-AawPptitRXp1y0n4ilKcGbRYWfbbzFWz2NqNu7dacYDtFtz0CMjG64b3LQsb3KIgnf4/obcUL78hfaOS7iCUfw==", + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true, - "dependencies": { - "@babel/helper-module-imports": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-remap-async-to-generator": "^7.22.20" - }, + "license": "MIT", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=8" } }, - "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.1.tgz", - "integrity": "sha512-TWWC18OShZutrv9C6mye1xwtam+uNi2bnTOCBUd5sZxyHOiWbU6ztSROofIMrK84uweEZC219POICK/sTYwfgg==", + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, + "license": "MIT", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">= 0.4" } }, - "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.5.tgz", - "integrity": "sha512-sMfBc3OxghjC95BkYrYocHL3NaOplrcaunblzwXhGmlPwpmfsxr4vK+mBBt49r+S240vahmv+kUxkeKgs+haCw==", + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.5" + "possible-typed-array-names": "^1.0.0" }, "engines": { - "node": ">=6.9.0" + "node": ">= 0.4" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.1.tgz", - "integrity": "sha512-OMLCXi0NqvJfORTaPQBwqLXHhb93wkBKZ4aNwMl6WtehO7ar+cmp+89iPEQPqxAnxsOKTaMcs3POz3rKayJ72g==", + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } + "license": "MIT" }, - "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.4.tgz", - "integrity": "sha512-B8q7Pz870Hz/q9UgP8InNpY01CSLDSCyqX7zcRuv3FcPl87A2G17lASroHWaCtbdIcbYzOZ7kWmXFKbijMSmFg==", + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.4", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" - } + "license": "ISC" }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.5.tgz", - "integrity": "sha512-gWkLP25DFj2dwe9Ck8uwMOpko4YsqyfZJrOmqqcegeDYEbp7rmn4U6UQZNj08UF6MaX39XenSpKRCvpDRBtZ7Q==", + "node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.24.5", - "@babel/helper-replace-supers": "^7.24.1", - "@babel/helper-split-export-declaration": "^7.24.5", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "balanced-match": "^1.0.0" } }, - "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.1.tgz", - "integrity": "sha512-5pJGVIUfJpOS+pAqBQd+QMaTD2vCL/HcePooON6pDpHgRp4gNRmzyHTPIkXntwKsq3ayUFVfJaIKPw2pOkOcTw==", + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/template": "^7.24.0" + "fill-range": "^7.1.1" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=8" } }, - "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.5.tgz", - "integrity": "sha512-SZuuLyfxvsm+Ah57I/i1HVjveBENYK9ue8MJ7qkc7ndoNjqquJiElzA7f5yaAXjyW2hKojosOTAQQRX50bPSVg==", + "node_modules/browser-or-node": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/browser-or-node/-/browser-or-node-3.0.0.tgz", + "integrity": "sha512-iczIdVJzGEYhP5DqQxYM9Hh7Ztpqqi+CXZpSmX8ALFs9ecXkQIeqRyM6TfxEfMVpwhl3dSuDvxdzzo9sUOIVBQ==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } + "license": "MIT" }, - "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.1.tgz", - "integrity": "sha512-p7uUxgSoZwZ2lPNMzUkqCts3xlp8n+o05ikjy7gbtFJSt9gdU88jAmtfmOxHM14noQXBxfgzf2yRWECiNVhTCw==", + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" }, "engines": { - "node": ">=6.9.0" + "node": ">= 0.4" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.1.tgz", - "integrity": "sha512-msyzuUnvsjsaSaocV6L7ErfNsa5nDWL1XKNnDePLgmz+WdU4w/J8+AxBMrWfi9m4IxfL5sZQKUPQKDQeeAT6lA==", + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">= 0.4" } }, - "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.1.tgz", - "integrity": "sha512-av2gdSTyXcJVdI+8aFZsCAtR29xJt0S5tas+Ef8NvBNmD1a+N/3ecMLeMBgfcK+xzsjdLDT6oHt+DFPyeqUbDA==", + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" }, "engines": { - "node": ">=6.9.0" + "node": ">= 0.4" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.1.tgz", - "integrity": "sha512-U1yX13dVBSwS23DEAqU+Z/PkwE9/m7QQy8Y9/+Tdb8UWYaGNDYwTLi19wqIAiROr8sXVum9A/rtiH5H0boUcTw==", + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, - "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" - }, + "license": "MIT", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=6" } }, - "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.1.tgz", - "integrity": "sha512-Ft38m/KFOyzKw2UaJFkWG9QnHPG/Q/2SkOrRk4pNBPg5IPZ+dOxcmkK5IyuBcxiNPyyYowPGUReyBvrvZs7IlQ==", + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - }, + "license": "MIT", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=6" } }, - "node_modules/@babel/plugin-transform-for-of": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.1.tgz", - "integrity": "sha512-OxBdcnF04bpdQdR3i4giHZNZQn7cm8RQKcSwA17wAAqEELo1ZOwp5FFgeptWUQXFyT9kwHo10aqqauYkRZPCAg==", + "node_modules/camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" }, "engines": { - "node": ">=6.9.0" + "node": ">=8" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@babel/plugin-transform-function-name": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.1.tgz", - "integrity": "sha512-BXmDZpPlh7jwicKArQASrj8n22/w6iymRnvHYYd2zO30DbE277JO20/7yXJT3QxDPtiQiOxQBbZH4TpivNXIxA==", + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.24.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=10" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.1.tgz", - "integrity": "sha512-U7RMFmRvoasscrIFy5xA4gIp8iWnWubnKkKuUGJjsuOH7GfbMkB+XZzeslx2kLdEGdOJDamEmCqOks6e8nv8DQ==", + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-json-strings": "^7.8.3" + "color-name": "~1.1.4" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=7.0.0" } }, - "node_modules/@babel/plugin-transform-literals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.1.tgz", - "integrity": "sha512-zn9pwz8U7nCqOYIiBaOxoQOtYmMODXTJnkxG4AtX8fPmnCRYWBOHD0qcpwS9e2VDSp1zNJYpdnFMIKb8jmwu6g==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", + "dev": true, + "license": "MIT" }, - "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.1.tgz", - "integrity": "sha512-OhN6J4Bpz+hIBqItTeWJujDOfNP+unqv/NJgyhlpSqgBTPm37KkMmZV6SYcOj+pnDbdcl1qRGV/ZiIjX9Iy34w==", + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } + "license": "MIT" + }, + "node_modules/confusing-browser-globals": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", + "dev": true, + "license": "MIT" }, - "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.1.tgz", - "integrity": "sha512-4ojai0KysTWXzHseJKa1XPNXKRbuUrhkOPY4rEGeR+7ChlJVKxFa3H3Bz+7tWaGKgJAXUWKOGmltN+u9B3+CVg==", + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=10" } }, - "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.1.tgz", - "integrity": "sha512-lAxNHi4HVtjnHd5Rxg3D5t99Xm6H7b04hUS7EHIXcUl2EV4yl1gWdqZrNzXnSrHveL9qMdbODlLF55mvgjAfaQ==", + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">= 8" } }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.1.tgz", - "integrity": "sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==", + "node_modules/css-functions-list": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.3.tgz", + "integrity": "sha512-IQOkD3hbR5KrN93MtcYuad6YPuTSUhntLHDuLEbFWE+ff2/XSZNdZG+LcbbIW5AXKg/WFIfYItIzVoHngHXZzA==", "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-simple-access": "^7.22.5" - }, + "license": "MIT", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=12 || >=16" } }, - "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.1.tgz", - "integrity": "sha512-mqQ3Zh9vFO1Tpmlt8QPnbwGHzNz3lpNEMxQb1kAemn/erstyqw1r9KeOlOfo3y6xAnFEcOv2tSyrXfmMk+/YZA==", + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true, - "dependencies": { - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-validator-identifier": "^7.22.20" + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=4" } }, - "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.1.tgz", - "integrity": "sha512-tuA3lpPj+5ITfcCluy6nWonSL7RvaG0AOTeAuvXqEKS34lnLzXpDb0dcP6K8jD0zWZFNDVly90AGFJPnm4fOYg==", + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0" + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" }, "engines": { - "node": ">=6.9.0" + "node": ">= 0.4" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", - "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" }, "engines": { - "node": ">=6.9.0" + "node": ">= 0.4" }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "funding": { + "url": "https://github.com/sponsors/inspect-js" } }, - "node_modules/@babel/plugin-transform-new-target": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.1.tgz", - "integrity": "sha512-/rurytBM34hYy0HKZQyA0nHbQgQNFm4Q/BOc9Hflxi2X3twRof7NaE5W46j4kQitm7SvACVRXsa6N/tSZxvPug==", + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" }, "engines": { - "node": ">=6.9.0" + "node": ">= 0.4" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.1.tgz", - "integrity": "sha512-iQ+caew8wRrhCikO5DrUYx0mrmdhkaELgFa+7baMcVuhxIkN7oxt06CZ51D65ugIb1UWRQ8oQe+HXAVM6qHFjw==", + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + "ms": "^2.1.3" }, "engines": { - "node": ">=6.9.0" + "node": ">=6.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.1.tgz", - "integrity": "sha512-7GAsGlK4cNL2OExJH1DzmDeKnRv/LXq0eLUSvudrehVA5Rgg4bIrqEUW29FbKMBRT0ztSqisv7kjP+XIC4ZMNw==", + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - }, + "license": "MIT", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=0.10.0" } }, - "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.5.tgz", - "integrity": "sha512-7EauQHszLGM3ay7a161tTQH7fj+3vVM/gThlz5HpFtnygTxjrlvoeq7MPVA1Vy9Q555OB8SnAOsMkLShNkkrHA==", + "node_modules/decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-plugin-utils": "^7.24.5", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.24.5" + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=0.10.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@babel/plugin-transform-object-super": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.1.tgz", - "integrity": "sha512-oKJqR3TeI5hSLRxudMjFQ9re9fBVUU0GICqM3J1mi8MqlhVr6hC/ZN4ttAyMuQR6EZZIY6h/exe5swqGNNIkWQ==", + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-replace-supers": "^7.24.1" - }, + "license": "MIT", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=0.10.0" } }, - "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.1.tgz", - "integrity": "sha512-oBTH7oURV4Y+3EUrf6cWn1OHio3qG/PVwO5J03iSJmBg6m2EhKjkAu/xuaXaYwWW9miYtvbWv4LNf0AmR43LUA==", + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, "engines": { - "node": ">=6.9.0" + "node": ">= 0.4" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.5.tgz", - "integrity": "sha512-xWCkmwKT+ihmA6l7SSTpk8e4qQl/274iNbSKRRS8mpqFR32ksy36+a+LWY8OXCCEefF8WFlnOHVsaDI2231wBg==", + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" }, "engines": { - "node": ">=6.9.0" + "node": ">= 0.4" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@babel/plugin-transform-parameters": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.5.tgz", - "integrity": "sha512-9Co00MqZ2aoky+4j2jhofErthm6QVLKbpQrvz20c3CH9KQCLHyNB+t2ya4/UrRpQGR+Wrwjg9foopoeSdnHOkA==", + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.5" + "path-type": "^4.0.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=8" } }, - "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.1.tgz", - "integrity": "sha512-tGvisebwBO5em4PaYNqt4fkw56K2VALsAbAakY0FjTYqJp7gfdrgr7YX76Or8/cpik0W6+tj3rZ0uHU9Oil4tw==", + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0" + "esutils": "^2.0.2" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=6.0.0" } }, - "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.5.tgz", - "integrity": "sha512-JM4MHZqnWR04jPMujQDTBVRnqxpLLpx2tkn7iPn+Hmsc0Gnb79yvRWOkvqFOx3Z7P7VxiRIR22c4eGSNj87OBQ==", + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.24.5", - "@babel/helper-plugin-utils": "^7.24.5", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, - "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.1.tgz", - "integrity": "sha512-LetvD7CrHmEx0G442gOomRr66d7q8HzzGGr4PMHGr+5YIm6++Yke+jxj246rpvsbyhJwCLxcTn6zW1P1BSenqA==", + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "domelementtype": "^2.3.0" }, "engines": { - "node": ">=6.9.0" + "node": ">= 4" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" } }, - "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.1.tgz", - "integrity": "sha512-sJwZBCzIBE4t+5Q4IGLaaun5ExVMRY0lYwos/jNecjMrVCygCdph3IKv0tkP5Fc87e/1+bebAmEAGBfnRD+cnw==", + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "regenerator-transform": "^0.15.2" - }, - "engines": { - "node": ">=6.9.0" + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" } }, - "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.1.tgz", - "integrity": "sha512-JAclqStUfIwKN15HrsQADFgeZt+wexNQ0uLhuqvqAUFoqPMjEcFCYZBhq0LUdz6dZK/mD+rErhW71fbx8RYElg==", + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">= 0.4" } }, - "node_modules/@babel/plugin-transform-runtime": { - "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.3.tgz", - "integrity": "sha512-J0BuRPNlNqlMTRJ72eVptpt9VcInbxO6iP3jaxr+1NPhC0UkKL+6oeX6VXMEYdADnuqmMmsBspt4d5w8Y/TCbQ==", + "node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", "dev": true, - "dependencies": { - "@babel/helper-module-imports": "^7.24.3", - "@babel/helper-plugin-utils": "^7.24.0", - "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.10.1", - "babel-plugin-polyfill-regenerator": "^0.6.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" + "license": "MIT" + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.1.tgz", - "integrity": "sha512-LyjVB1nsJ6gTTUKRjRWx9C1s9hE7dLfP/knKdrfeH9UPtAGjYGgxIbFfx7xyLIEWs7Xe1Gnf8EWiUqfjLhInZA==", + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "is-arrayish": "^0.2.1" } }, - "node_modules/@babel/plugin-transform-spread": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.1.tgz", - "integrity": "sha512-KjmcIM+fxgY+KxPVbjelJC6hrH1CgtPmTvdXAfn3/a9CnWGSTY7nH4zm5+cjmWJybdcPSsD0++QssDsjcpe47g==", + "node_modules/es-abstract": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", + "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" }, "engines": { - "node": ">=6.9.0" + "node": ">= 0.4" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.1.tgz", - "integrity": "sha512-9v0f1bRXgPVcPrngOQvLXeGNNVLc8UjMVfebo9ka0WF3/7+aVUHmaJVT3sa0XCzEFioPfPHZiOcYG9qOsH63cw==", + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, + "license": "MIT", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">= 0.4" } }, - "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.1.tgz", - "integrity": "sha512-WRkhROsNzriarqECASCNu/nojeXCDTE/F2HmRgOzi7NGvyfYGq1NEjKBK3ckLfRgGc6/lPAqP0vDOSw3YtG34g==", + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, + "license": "MIT", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">= 0.4" } }, - "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.5.tgz", - "integrity": "sha512-UTGnhYVZtTAjdwOTzT+sCyXmTn8AhaxOS/MjG9REclZ6ULHWF9KoCZur0HSGU7hk8PdBFKKbYe6+gqdXWz84Jg==", + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.5" + "es-errors": "^1.3.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">= 0.4" } }, - "node_modules/@babel/plugin-transform-typescript": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.5.tgz", - "integrity": "sha512-E0VWu/hk83BIFUWnsKZ4D81KXjN5L3MobvevOHErASk9IPwKHOkTgvqzvNo1yP/ePJWqqK2SpUR5z+KQbl6NVw==", + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.24.5", - "@babel/helper-plugin-utils": "^7.24.5", - "@babel/plugin-syntax-typescript": "^7.24.1" + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">= 0.4" } }, - "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.1.tgz", - "integrity": "sha512-RlkVIcWT4TLI96zM660S877E7beKlQw7Ig+wqkKBiWfj0zH5Q4h50q6er4wzZKRNSYpfo6ILJ+hrJAGSX2qcNw==", + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "hasown": "^2.0.2" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">= 0.4" } }, - "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.1.tgz", - "integrity": "sha512-Ss4VvlfYV5huWApFsF8/Sq0oXnGO+jB+rijFEFugTd3cwSObUSnUi88djgR5528Csl0uKlrI331kRqe56Ov2Ng==", + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" }, "engines": { - "node": ">=6.9.0" + "node": ">= 0.4" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.1.tgz", - "integrity": "sha512-2A/94wgZgxfTsiLaQ2E36XAOdcZmGAaEEgVmxQWwZXWkGhvoHbaqXcKnU8zny4ycpu3vNqg0L/PcCiYtHtA13g==", + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" - }, + "license": "MIT", "engines": { - "node": ">=6.9.0" + "node": ">=10" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.1.tgz", - "integrity": "sha512-fqj4WuzzS+ukpgerpAoOnMfQXwUHFxXUZUE84oL2Kao2N8uSlvcpnAidKASgsNgzZHBsHWvcm8s9FPWUhAb8fA==", + "node_modules/eslint": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/preset-env": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.5.tgz", - "integrity": "sha512-UGK2ifKtcC8i5AI4cH+sbLLuLc2ktYSFJgBAXorKAsHUZmrQ1q6aQ6i3BvU24wWs2AAKqQB6kq3N9V9Gw1HiMQ==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.24.4", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-plugin-utils": "^7.24.5", - "@babel/helper-validator-option": "^7.23.5", - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.5", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.1", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.1", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.1", - "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.24.1", - "@babel/plugin-syntax-import-attributes": "^7.24.1", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.24.1", - "@babel/plugin-transform-async-generator-functions": "^7.24.3", - "@babel/plugin-transform-async-to-generator": "^7.24.1", - "@babel/plugin-transform-block-scoped-functions": "^7.24.1", - "@babel/plugin-transform-block-scoping": "^7.24.5", - "@babel/plugin-transform-class-properties": "^7.24.1", - "@babel/plugin-transform-class-static-block": "^7.24.4", - "@babel/plugin-transform-classes": "^7.24.5", - "@babel/plugin-transform-computed-properties": "^7.24.1", - "@babel/plugin-transform-destructuring": "^7.24.5", - "@babel/plugin-transform-dotall-regex": "^7.24.1", - "@babel/plugin-transform-duplicate-keys": "^7.24.1", - "@babel/plugin-transform-dynamic-import": "^7.24.1", - "@babel/plugin-transform-exponentiation-operator": "^7.24.1", - "@babel/plugin-transform-export-namespace-from": "^7.24.1", - "@babel/plugin-transform-for-of": "^7.24.1", - "@babel/plugin-transform-function-name": "^7.24.1", - "@babel/plugin-transform-json-strings": "^7.24.1", - "@babel/plugin-transform-literals": "^7.24.1", - "@babel/plugin-transform-logical-assignment-operators": "^7.24.1", - "@babel/plugin-transform-member-expression-literals": "^7.24.1", - "@babel/plugin-transform-modules-amd": "^7.24.1", - "@babel/plugin-transform-modules-commonjs": "^7.24.1", - "@babel/plugin-transform-modules-systemjs": "^7.24.1", - "@babel/plugin-transform-modules-umd": "^7.24.1", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", - "@babel/plugin-transform-new-target": "^7.24.1", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.1", - "@babel/plugin-transform-numeric-separator": "^7.24.1", - "@babel/plugin-transform-object-rest-spread": "^7.24.5", - "@babel/plugin-transform-object-super": "^7.24.1", - "@babel/plugin-transform-optional-catch-binding": "^7.24.1", - "@babel/plugin-transform-optional-chaining": "^7.24.5", - "@babel/plugin-transform-parameters": "^7.24.5", - "@babel/plugin-transform-private-methods": "^7.24.1", - "@babel/plugin-transform-private-property-in-object": "^7.24.5", - "@babel/plugin-transform-property-literals": "^7.24.1", - "@babel/plugin-transform-regenerator": "^7.24.1", - "@babel/plugin-transform-reserved-words": "^7.24.1", - "@babel/plugin-transform-shorthand-properties": "^7.24.1", - "@babel/plugin-transform-spread": "^7.24.1", - "@babel/plugin-transform-sticky-regex": "^7.24.1", - "@babel/plugin-transform-template-literals": "^7.24.1", - "@babel/plugin-transform-typeof-symbol": "^7.24.5", - "@babel/plugin-transform-unicode-escapes": "^7.24.1", - "@babel/plugin-transform-unicode-property-regex": "^7.24.1", - "@babel/plugin-transform-unicode-regex": "^7.24.1", - "@babel/plugin-transform-unicode-sets-regex": "^7.24.1", - "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.10.4", - "babel-plugin-polyfill-regenerator": "^0.6.1", - "core-js-compat": "^3.31.0", - "semver": "^6.3.1" + "bin": { + "eslint": "bin/eslint.js" }, "engines": { - "node": ">=6.9.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@babel/preset-modules": { - "version": "0.1.6-no-external-plugins", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", - "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "node_modules/eslint-config-airbnb-base": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz", + "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" + "confusing-browser-globals": "^1.0.10", + "object.assign": "^4.1.2", + "object.entries": "^1.1.5", + "semver": "^6.3.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + "eslint": "^7.32.0 || ^8.2.0", + "eslint-plugin-import": "^2.25.2" } }, - "node_modules/@babel/preset-typescript": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.24.1.tgz", - "integrity": "sha512-1DBaMmRDpuYQBPWD8Pf/WEwCrtgRHxsZnP4mIy9G/X+hFfbI47Q2G4t1Paakld84+qsk2fSsUPMKg71jkoOOaQ==", + "node_modules/eslint-config-airbnb-base/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-validator-option": "^7.23.5", - "@babel/plugin-syntax-jsx": "^7.24.1", - "@babel/plugin-transform-modules-commonjs": "^7.24.1", - "@babel/plugin-transform-typescript": "^7.24.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "license": "ISC", + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/@babel/register": { - "version": "7.23.7", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.23.7.tgz", - "integrity": "sha512-EjJeB6+kvpk+Y5DAkEAmbOBEFkh9OASx0huoEkqYTFxAZHzOAX2Oh5uwAUuL2rUddqfM0SA+KPXV2TbzoZ2kvQ==", + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", "dev": true, - "dependencies": { - "clone-deep": "^4.0.1", - "find-cache-dir": "^2.0.0", - "make-dir": "^2.1.0", - "pirates": "^4.0.6", - "source-map-support": "^0.5.16" - }, - "engines": { - "node": ">=6.9.0" + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "eslint": ">=7.0.0" } }, - "node_modules/@babel/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", - "dev": true - }, - "node_modules/@babel/runtime": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz", - "integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==", + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, + "license": "MIT", "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" } }, - "node_modules/@babel/template": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", - "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/parser": "^7.24.0", - "@babel/types": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" + "ms": "^2.1.1" } }, - "node_modules/@babel/traverse": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.5.tgz", - "integrity": "sha512-7aaBLeDQ4zYcUFDUD41lJc1fG8+5IU9DaNSJAgal866FGvmD5EbWQgnEC6kO1gGLsX0esNkfnJSndbTXA3r7UA==", + "node_modules/eslint-module-utils": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", + "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.2", - "@babel/generator": "^7.24.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.24.5", - "@babel/parser": "^7.24.5", - "@babel/types": "^7.24.5", - "debug": "^4.3.1", - "globals": "^11.1.0" + "debug": "^3.2.7" }, "engines": { - "node": ">=6.9.0" + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } } }, - "node_modules/@babel/types": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.5.tgz", - "integrity": "sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ==", + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.24.1", - "@babel/helper-validator-identifier": "^7.24.5", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" + "ms": "^2.1.1" } }, - "node_modules/@csstools/css-parser-algorithms": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.4.tgz", - "integrity": "sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A==", + "node_modules/eslint-plugin-file-progress": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-file-progress/-/eslint-plugin-file-progress-1.5.0.tgz", + "integrity": "sha512-get8oNfacIagP+igSzrEZhepPgodtdwACVeKQsE1fVvTL15tZvgCv8K4B2lKT4FZOZOyhxSkQGnWyjEOx1uoIw==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], "license": "MIT", - "engines": { - "node": ">=18" + "dependencies": { + "nanospinner": "^1.1.0", + "picocolors": "^1.0.1" }, "peerDependencies": { - "@csstools/css-tokenizer": "^3.0.3" + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" } }, - "node_modules/@csstools/css-tokenizer": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.3.tgz", - "integrity": "sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw==", + "node_modules/eslint-plugin-filename-rules": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-filename-rules/-/eslint-plugin-filename-rules-1.3.1.tgz", + "integrity": "sha512-kBMxGFvK3QrRBHMurhFSNa+PFdszezVtBV6egg39TDzlj6D4jL3Xx6oyNjm5xE4C+TdQUBzWwymHJHBPyxOreA==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], "license": "MIT", "engines": { - "node": ">=18" + "node": ">=6.0.0" } }, - "node_modules/@csstools/media-query-list-parser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.2.tgz", - "integrity": "sha512-EUos465uvVvMJehckATTlNqGj4UJWkTmdWuDMjqvSUkjGpmOyFZBVwb4knxCm/k2GMTXY+c/5RkdndzFYWeX5A==", + "node_modules/eslint-plugin-html": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-7.1.0.tgz", + "integrity": "sha512-fNLRraV/e6j8e3XYOC9xgND4j+U7b1Rq+OygMlLcMg+wI/IpVbF+ubQa3R78EjKB9njT6TQOlcK5rFKBVVtdfg==", + "dev": true, + "license": "ISC", + "dependencies": { + "htmlparser2": "^8.0.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", + "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], "license": "MIT", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.8", + "array.prototype.findlastindex": "^1.2.5", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.0", + "hasown": "^2.0.2", + "is-core-module": "^2.15.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.0", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.8", + "tsconfig-paths": "^3.15.0" + }, "engines": { - "node": ">=18" + "node": ">=4" }, "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.4", - "@csstools/css-tokenizer": "^3.0.3" + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" } }, - "node_modules/@dual-bundle/import-meta-resolve": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@dual-bundle/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", - "integrity": "sha512-+nxncfwHM5SgAtrVzgpzJOI1ol0PkumhVo469KCf9lUi21IGcY90G98VuHm9VRrUypmAzawAHO9bs6hqeADaVg==", + "node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.1.tgz", - "integrity": "sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==", - "cpu": [ - "ppc64" - ], + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "peer": true, - "engines": { - "node": ">=18" + "dependencies": { + "ms": "^2.1.1" } }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.1.tgz", - "integrity": "sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==", - "cpu": [ - "arm" - ], + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "peer": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, "engines": { - "node": ">=18" + "node": ">=0.10.0" } }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.1.tgz", - "integrity": "sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==", - "cpu": [ - "arm64" - ], + "node_modules/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "peer": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, "engines": { - "node": ">=18" + "node": "*" } }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.1.tgz", - "integrity": "sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==", - "cpu": [ - "x64" - ], + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "peer": true, - "engines": { - "node": ">=18" + "license": "ISC", + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.1.tgz", - "integrity": "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==", - "cpu": [ - "arm64" - ], + "node_modules/eslint-plugin-inclusive-language": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-inclusive-language/-/eslint-plugin-inclusive-language-2.2.1.tgz", + "integrity": "sha512-RL6avDWXCS0Dcp9axhvHRUp65qG07qjOrh6J4BNNahPvRY3PuYGnAd0H1strZ9cob79JiEW4Bq0j3gEuzbv0/A==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": ">=18" + "license": "CC0-1.0", + "dependencies": { + "humps": "^2.0.1" } }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.1.tgz", - "integrity": "sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==", - "cpu": [ - "x64" - ], + "node_modules/eslint-plugin-vue": { + "version": "9.32.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.32.0.tgz", + "integrity": "sha512-b/Y05HYmnB/32wqVcjxjHZzNpwxj1onBOvqW89W+V+XNG1dRuaFbNd3vT9CLbr2LXjEoq+3vn8DanWf7XU22Ug==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "peer": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "globals": "^13.24.0", + "natural-compare": "^1.4.0", + "nth-check": "^2.1.1", + "postcss-selector-parser": "^6.0.15", + "semver": "^7.6.3", + "vue-eslint-parser": "^9.4.3", + "xml-name-validator": "^4.0.0" + }, "engines": { - "node": ">=18" + "node": "^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" } }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.1.tgz", - "integrity": "sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==", - "cpu": [ - "arm64" - ], + "node_modules/eslint-plugin-vuejs-accessibility": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-vuejs-accessibility/-/eslint-plugin-vuejs-accessibility-2.4.1.tgz", + "integrity": "sha512-ZRZhPdslplZXSF71MtSG+zXYRAT5KiHR4JVuo/DERQf9noAkDvi5W418VOE1qllmJd7wTenndxi1q8XeDMxdHw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "peer": true, + "dependencies": { + "aria-query": "^5.3.0", + "emoji-regex": "^10.0.0", + "vue-eslint-parser": "^9.0.1" + }, "engines": { - "node": ">=18" + "node": ">=16.0.0" + }, + "peerDependencies": { + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" } }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.1.tgz", - "integrity": "sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==", - "cpu": [ - "x64" - ], + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "peer": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, "engines": { - "node": ">=18" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.1.tgz", - "integrity": "sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==", - "cpu": [ - "arm" - ], + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, + "license": "Apache-2.0", "engines": { - "node": ">=18" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.1.tgz", - "integrity": "sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==", - "cpu": [ - "arm64" - ], + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.1.tgz", - "integrity": "sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==", - "cpu": [ - "ia32" - ], + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, "engines": { - "node": ">=18" + "node": "*" } }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.1.tgz", - "integrity": "sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==", - "cpu": [ - "loong64" - ], + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, "engines": { - "node": ">=18" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.1.tgz", - "integrity": "sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==", - "cpu": [ - "mips64el" - ], + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, "engines": { - "node": ">=18" + "node": ">=0.10" } }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.1.tgz", - "integrity": "sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==", - "cpu": [ - "ppc64" - ], + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, "engines": { - "node": ">=18" + "node": ">=4.0" } }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.1.tgz", - "integrity": "sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==", - "cpu": [ - "riscv64" - ], + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, + "license": "BSD-2-Clause", "engines": { - "node": ">=18" + "node": ">=4.0" } }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.1.tgz", - "integrity": "sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==", - "cpu": [ - "s390x" - ], + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } + "license": "MIT" }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.1.tgz", - "integrity": "sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==", - "cpu": [ - "x64" - ], + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, + "license": "BSD-2-Clause", "engines": { - "node": ">=18" + "node": ">=0.10.0" } }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.1.tgz", - "integrity": "sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==", - "cpu": [ - "arm64" - ], + "node_modules/expect-type": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-0.15.0.tgz", + "integrity": "sha512-yWnriYB4e8G54M5/fAFj7rCIBiKs1HAACaY13kCz6Ku0dezjS9aMcfcdVK2X8Tv2tEV1BPz/wKfQ7WA4S/d8aA==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "peer": true, - "engines": { - "node": ">=18" - } + "license": "Apache-2.0" }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.1.tgz", - "integrity": "sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==", - "cpu": [ - "x64" - ], + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "peer": true, - "engines": { - "node": ">=18" - } + "license": "MIT" }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.1.tgz", - "integrity": "sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==", - "cpu": [ - "arm64" - ], + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "peer": true, - "engines": { - "node": ">=18" + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" } }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.1.tgz", - "integrity": "sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==", - "cpu": [ - "x64" - ], + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "peer": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, "engines": { - "node": ">=18" + "node": ">= 6" } }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.1.tgz", - "integrity": "sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==", - "cpu": [ - "x64" - ], + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "peer": true, - "engines": { - "node": ">=18" - } + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.1.tgz", - "integrity": "sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==", - "cpu": [ - "arm64" + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } ], + "license": "BSD-3-Clause" + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "peer": true, "engines": { - "node": ">=18" + "node": ">= 4.9.1" } }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.1.tgz", - "integrity": "sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==", - "cpu": [ - "ia32" - ], + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "engines": { - "node": ">=18" + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" } }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.1.tgz", - "integrity": "sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==", - "cpu": [ - "x64" - ], + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "peer": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, "engines": { - "node": ">=18" + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", "dependencies": { - "eslint-visitor-keys": "^3.3.0" + "to-regex-range": "^5.0.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + "node": ">=8" } }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=10" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@eslint-community/regexpp": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", "dev": true, + "license": "MIT", "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" + "is-callable": "^1.2.7" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">= 0.4" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@eslint/eslintrc/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" }, - "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", "dev": true, + "license": "MIT", "dependencies": { - "type-fest": "^0.20.2" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" }, "engines": { - "node": ">=8" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@eslint/eslintrc/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, + "license": "MIT", "engines": { - "node": "*" + "node": ">= 0.4" } }, - "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "dev": true, + "license": "MIT", "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" }, "engines": { - "node": ">=10.10.0" + "node": ">= 0.4" } }, - "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", "dev": true, + "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { - "brace-expansion": "^1.1.7" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" }, "engines": { "node": "*" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "dev": true - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "license": "ISC", "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" + "is-glob": "^4.0.3" }, "engines": { - "node": ">=8" + "node": ">=10.13.0" } }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, - "engines": { - "node": ">=8" + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { - "@sinclair/typebox": "^0.27.8" + "brace-expansion": "^1.1.7" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "*" } }, - "node_modules/@jest/transform": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", - "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.2" + "global-prefix": "^3.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=6" } }, - "node_modules/@jest/transform/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", "dev": true, + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">=6" } }, - "node_modules/@jest/transform/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, + "license": "ISC", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" + "isexe": "^2.0.0" }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "bin": { + "which": "bin/which" } }, - "node_modules/@jest/transform/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, + "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "type-fest": "^0.20.2" }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/transform/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/@jest/transform/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@jest/transform/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", "dev": true, + "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "define-properties": "^1.2.1", + "gopd": "^1.0.1" }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@jest/types": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@jest/types/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/globjoin": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", + "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, + "license": "MIT" + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@jest/types/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, + "license": "MIT" + }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">=6" } }, - "node_modules/@jest/types/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/has": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", + "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, + "license": "MIT", "engines": { - "node": ">=7.0.0" + "node": ">= 0.4.0" } }, - "node_modules/@jest/types/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/@jest/types/node_modules/has-flag": { + "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/@jest/types/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, + "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "es-define-property": "^1.0.0" }, - "engines": { - "node": ">=8" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" + "dunder-proto": "^1.0.0" }, "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "engines": { - "node": ">=6.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "dev": true, + "license": "MIT", "engines": { - "node": ">=6.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@keyv/serialize": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.0.3.tgz", - "integrity": "sha512-qnEovoOp5Np2JDGonIDL6Ayihw0RhnRh6vxPuHo4RDn1UOzwEo4AeIfpL6UGIrsceWrCMiVPgwRjbHu4vYFc3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer": "^6.0.3" - } - }, - "node_modules/@keyv/serialize/node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { - "version": "5.1.1-v1", - "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", - "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", - "dev": true, - "dependencies": { - "eslint-scope": "5.1.1" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.37.0.tgz", - "integrity": "sha512-l7StVw6WAa8l3vA1ov80jyetOAEo1FtHvZDbzXDO/02Sq/QVvqlHkYoFwDJPIMj0GKiistsBudfx5tGFnwYWDQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "peer": true - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.37.0.tgz", - "integrity": "sha512-6U3SlVyMxezt8Y+/iEBcbp945uZjJwjZimu76xoG7tO1av9VO691z8PkhzQ85ith2I8R2RddEPeSfcbyPfD4hA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "peer": true - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.37.0.tgz", - "integrity": "sha512-+iTQ5YHuGmPt10NTzEyMPbayiNTcOZDWsbxZYR1ZnmLnZxG17ivrPSWFO9j6GalY0+gV3Jtwrrs12DBscxnlYA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "peer": true - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.37.0.tgz", - "integrity": "sha512-m8W2UbxLDcmRKVjgl5J/k4B8d7qX2EcJve3Sut7YGrQoPtCIQGPH5AMzuFvYRWZi0FVS0zEY4c8uttPfX6bwYQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "peer": true - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.37.0.tgz", - "integrity": "sha512-FOMXGmH15OmtQWEt174v9P1JqqhlgYge/bUjIbiVD1nI1NeJ30HYT9SJlZMqdo1uQFyt9cz748F1BHghWaDnVA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "peer": true - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.37.0.tgz", - "integrity": "sha512-SZMxNttjPKvV14Hjck5t70xS3l63sbVwl98g3FlVVx2YIDmfUIy29jQrsw06ewEYQ8lQSuY9mpAPlmgRD2iSsA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "peer": true - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.37.0.tgz", - "integrity": "sha512-hhAALKJPidCwZcj+g+iN+38SIOkhK2a9bqtJR+EtyxrKKSt1ynCBeqrQy31z0oWU6thRZzdx53hVgEbRkuI19w==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.37.0.tgz", - "integrity": "sha512-jUb/kmn/Gd8epbHKEqkRAxq5c2EwRt0DqhSGWjPFxLeFvldFdHQs/n8lQ9x85oAeVb6bHcS8irhTJX2FCOd8Ag==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.37.0.tgz", - "integrity": "sha512-oNrJxcQT9IcbcmKlkF+Yz2tmOxZgG9D9GRq+1OE6XCQwCVwxixYAa38Z8qqPzQvzt1FCfmrHX03E0pWoXm1DqA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.37.0.tgz", - "integrity": "sha512-pfxLBMls+28Ey2enpX3JvjEjaJMBX5XlPCZNGxj4kdJyHduPBXtxYeb8alo0a7bqOoWZW2uKynhHxF/MWoHaGQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.37.0.tgz", - "integrity": "sha512-yCE0NnutTC/7IGUq/PUHmoeZbIwq3KRh02e9SfFh7Vmc1Z7atuJRYWhRME5fKgT8aS20mwi1RyChA23qSyRGpA==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.37.0.tgz", - "integrity": "sha512-NxcICptHk06E2Lh3a4Pu+2PEdZ6ahNHuK7o6Np9zcWkrBMuv21j10SQDJW3C9Yf/A/P7cutWoC/DptNLVsZ0VQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.37.0.tgz", - "integrity": "sha512-PpWwHMPCVpFZLTfLq7EWJWvrmEuLdGn1GMYcm5MV7PaRgwCEYJAwiN94uBuZev0/J/hFIIJCsYw4nLmXA9J7Pw==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.37.0.tgz", - "integrity": "sha512-DTNwl6a3CfhGTAOYZ4KtYbdS8b+275LSLqJVJIrPa5/JuIufWWZ/QFvkxp52gpmguN95eujrM68ZG+zVxa8zHA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.37.0.tgz", - "integrity": "sha512-hZDDU5fgWvDdHFuExN1gBOhCuzo/8TMpidfOR+1cPZJflcEzXdCy1LjnklQdW8/Et9sryOPJAKAQRw8Jq7Tg+A==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.37.0.tgz", - "integrity": "sha512-pKivGpgJM5g8dwj0ywBwe/HeVAUSuVVJhUTa/URXjxvoyTT/AxsLTAbkHkDHG7qQxLoW2s3apEIl26uUe08LVQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.37.0.tgz", - "integrity": "sha512-E2lPrLKE8sQbY/2bEkVTGDEk4/49UYRVWgj90MY8yPjpnGBQ+Xi1Qnr7b7UIWw1NOggdFQFOLZ8+5CzCiz143w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.37.0.tgz", - "integrity": "sha512-Jm7biMazjNzTU4PrQtr7VS8ibeys9Pn29/1bm4ph7CP2kf21950LgN+BaE2mJ1QujnvOc6p54eWWiVvn05SOBg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "peer": true - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.37.0.tgz", - "integrity": "sha512-e3/1SFm1OjefWICB2Ucstg2dxYDkDTZGDYgwufcbsxTHyqQps1UQf33dFEChBNmeSsTOyrjw2JJq0zbG5GF6RA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "peer": true - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.37.0.tgz", - "integrity": "sha512-LWbXUBwn/bcLx2sSsqy7pK5o+Nr+VCoRoAohfJ5C/aBio9nfJmGQqHAhU6pwxV/RmyTk5AqdySma7uwWGlmeuA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "peer": true - }, - "node_modules/@shopware-ag/eslint-config-base": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@shopware-ag/eslint-config-base/-/eslint-config-base-2.0.0.tgz", - "integrity": "sha512-G7VOfkg9SsybDfCohUB+YRcn/yaTzxQfNLfNdmvE03BK7kh0f2edwUu64FfQKMcRzVmL8lvu/sl4oErTJsNsQA==", - "dev": true, - "dependencies": { - "eslint": "^8.29.0", - "eslint-config-airbnb-base": "^15.0.0", - "eslint-plugin-import": "2.26.0" - } - }, - "node_modules/@shopware-ag/eslint-config-base/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@shopware-ag/eslint-config-base/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/@shopware-ag/eslint-config-base/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@shopware-ag/eslint-config-base/node_modules/eslint-plugin-import": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", - "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", - "dev": true, - "dependencies": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.3", - "has": "^1.0.3", - "is-core-module": "^2.8.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.values": "^1.1.5", - "resolve": "^1.22.0", - "tsconfig-paths": "^3.14.1" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "node_modules/@shopware-ag/eslint-config-base/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@shopware-ag/eslint-config-base/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/@shopware-ag/meteor-tokens": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@shopware-ag/meteor-tokens/-/meteor-tokens-1.0.0.tgz", - "integrity": "sha512-MdxJdmbHvrGdesuXuIfU2NujryaU+HByuf5FMIgK2xJ7dTWzQZWAj/+mR5Pt9+mOQTP9Gy/pBtoAzznT5/wrug==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "dotenv": "^16.4.7", - "ora": "^8.2.0", - "vitest": "^3.0.6", - "zod": "^3.24.2" - } - }, - "node_modules/@shopware-ag/meteor-tokens/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@shopware-ag/meteor-tokens/node_modules/chalk": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", - "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@shopware-ag/meteor-tokens/node_modules/cli-cursor": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", - "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "restore-cursor": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@shopware-ag/meteor-tokens/node_modules/is-interactive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", - "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@shopware-ag/meteor-tokens/node_modules/is-unicode-supported": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", - "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@shopware-ag/meteor-tokens/node_modules/log-symbols": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz", - "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "chalk": "^5.3.0", - "is-unicode-supported": "^1.3.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@shopware-ag/meteor-tokens/node_modules/log-symbols/node_modules/is-unicode-supported": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", - "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@shopware-ag/meteor-tokens/node_modules/onetime": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", - "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "mimic-function": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@shopware-ag/meteor-tokens/node_modules/ora": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/ora/-/ora-8.2.0.tgz", - "integrity": "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "chalk": "^5.3.0", - "cli-cursor": "^5.0.0", - "cli-spinners": "^2.9.2", - "is-interactive": "^2.0.0", - "is-unicode-supported": "^2.0.0", - "log-symbols": "^6.0.0", - "stdin-discarder": "^0.2.2", - "string-width": "^7.2.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@shopware-ag/meteor-tokens/node_modules/restore-cursor": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", - "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "onetime": "^7.0.0", - "signal-exit": "^4.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@shopware-ag/meteor-tokens/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "license": "ISC", - "peer": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@shopware-ag/meteor-tokens/node_modules/string-width": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@shopware-ag/meteor-tokens/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@shopware-ag/stylelint-plugin-meteor": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@shopware-ag/stylelint-plugin-meteor/-/stylelint-plugin-meteor-1.1.0.tgz", - "integrity": "sha512-x55+bznbjwWd4B3GEtfnY7ORQTyY2/XLaot2GP6+O0AW26pCylD+MnVm0KwkW8qujCnvnl0tKWGKHn8c6jmeVA==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@shopware-ag/meteor-tokens": "1.0.0", - "stylelint": "^16.10.0" - } - }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true - }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz", - "integrity": "sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==", - "dev": true, - "dependencies": { - "@babel/types": "^7.20.7" - } - }, - "node_modules/@types/eslint": { - "version": "8.56.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", - "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", - "dev": true, - "peer": true, - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "dev": true, - "peer": true, - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/@types/graceful-fs": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", - "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "dev": true - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, - "peer": true - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true - }, - "node_modules/@types/node": { - "version": "20.12.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz", - "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==", - "dev": true, - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "dev": true - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.9.0.tgz", - "integrity": "sha512-6e+X0X3sFe/G/54aC3jt0txuMTURqLyekmEHViqyA2VnxhLMpvA6nqmcjIy+Cr9tLDHPssA74BP5Mx9HQIxBEA==", - "dev": true, - "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.9.0", - "@typescript-eslint/type-utils": "7.9.0", - "@typescript-eslint/utils": "7.9.0", - "@typescript-eslint/visitor-keys": "7.9.0", - "graphemer": "^1.4.0", - "ignore": "^5.3.1", - "natural-compare": "^1.4.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.9.0.tgz", - "integrity": "sha512-qHMJfkL5qvgQB2aLvhUSXxbK7OLnDkwPzFalg458pxQgfxKDfT1ZDbHQM/I6mDIf/svlMkj21kzKuQ2ixJlatQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "7.9.0", - "@typescript-eslint/types": "7.9.0", - "@typescript-eslint/typescript-estree": "7.9.0", - "@typescript-eslint/visitor-keys": "7.9.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.9.0.tgz", - "integrity": "sha512-ZwPK4DeCDxr3GJltRz5iZejPFAAr4Wk3+2WIBaj1L5PYK5RgxExu/Y68FFVclN0y6GGwH8q+KgKRCvaTmFBbgQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.9.0", - "@typescript-eslint/visitor-keys": "7.9.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.9.0.tgz", - "integrity": "sha512-6Qy8dfut0PFrFRAZsGzuLoM4hre4gjzWJB6sUvdunCYZsYemTkzZNwF1rnGea326PHPT3zn5Lmg32M/xfJfByA==", - "dev": true, - "dependencies": { - "@typescript-eslint/typescript-estree": "7.9.0", - "@typescript-eslint/utils": "7.9.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.9.0.tgz", - "integrity": "sha512-oZQD9HEWQanl9UfsbGVcZ2cGaR0YT5476xfWE0oE5kQa2sNK2frxOlkeacLOTh9po4AlUT5rtkGyYM5kew0z5w==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.9.0.tgz", - "integrity": "sha512-zBCMCkrb2YjpKV3LA0ZJubtKCDxLttxfdGmwZvTqqWevUPN0FZvSI26FalGFFUZU/9YQK/A4xcQF9o/VVaCKAg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.9.0", - "@typescript-eslint/visitor-keys": "7.9.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.9.0.tgz", - "integrity": "sha512-5KVRQCzZajmT4Ep+NEgjXCvjuypVvYHUW7RHlXzNPuak2oWpVoD1jf5xCP0dPAuNIchjC7uQyvbdaSTFaLqSdA==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.9.0", - "@typescript-eslint/types": "7.9.0", - "@typescript-eslint/typescript-estree": "7.9.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.9.0.tgz", - "integrity": "sha512-iESPx2TNLDNGQLyjKhUvIKprlP49XNEK+MvIf9nIO7ZZaZdbnfWKHnXAgufpxqfA0YryH8XToi4+CjBgVnFTSQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.9.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, - "node_modules/@vitest/expect": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.0.9.tgz", - "integrity": "sha512-5eCqRItYgIML7NNVgJj6TVCmdzE7ZVgJhruW0ziSQV4V7PvLkDL1bBkBdcTs/VuIz0IxPb5da1IDSqc1TR9eig==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@vitest/spy": "3.0.9", - "@vitest/utils": "3.0.9", - "chai": "^5.2.0", - "tinyrainbow": "^2.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/mocker": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.0.9.tgz", - "integrity": "sha512-ryERPIBOnvevAkTq+L1lD+DTFBRcjueL9lOUfXsLfwP92h4e+Heb+PjiqS3/OURWPtywfafK0kj++yDFjWUmrA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@vitest/spy": "3.0.9", - "estree-walker": "^3.0.3", - "magic-string": "^0.30.17" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "msw": "^2.4.9", - "vite": "^5.0.0 || ^6.0.0" - }, - "peerDependenciesMeta": { - "msw": { - "optional": true - }, - "vite": { - "optional": true - } - } - }, - "node_modules/@vitest/pretty-format": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.0.9.tgz", - "integrity": "sha512-OW9F8t2J3AwFEwENg3yMyKWweF7oRJlMyHOMIhO5F3n0+cgQAJZBjNgrF8dLwFTEXl5jUqBLXd9QyyKv8zEcmA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "tinyrainbow": "^2.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/runner": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.0.9.tgz", - "integrity": "sha512-NX9oUXgF9HPfJSwl8tUZCMP1oGx2+Sf+ru6d05QjzQz4OwWg0psEzwY6VexP2tTHWdOkhKHUIZH+fS6nA7jfOw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@vitest/utils": "3.0.9", - "pathe": "^2.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/snapshot": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.0.9.tgz", - "integrity": "sha512-AiLUiuZ0FuA+/8i19mTYd+re5jqjEc2jZbgJ2up0VY0Ddyyxg/uUtBDpIFAy4uzKaQxOW8gMgBdAJJ2ydhu39A==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@vitest/pretty-format": "3.0.9", - "magic-string": "^0.30.17", - "pathe": "^2.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/spy": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.0.9.tgz", - "integrity": "sha512-/CcK2UDl0aQ2wtkp3YVWldrpLRNCfVcIOFGlVGKO4R5eajsH393Z1yiXLVQ7vWsj26JOEjeZI0x5sm5P4OGUNQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "tinyspy": "^3.0.2" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/utils": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.0.9.tgz", - "integrity": "sha512-ilHM5fHhZ89MCp5aAaM9uhfl1c2JdxVxl3McqsdVyVNN6JffnEen8UMCdRTzOhGXNQGo5GNL9QugHrz727Wnng==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@vitest/pretty-format": "3.0.9", - "loupe": "^3.1.3", - "tinyrainbow": "^2.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", - "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", - "dev": true, - "peer": true, - "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", - "dev": true, - "peer": true - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", - "dev": true, - "peer": true - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", - "dev": true, - "peer": true - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", - "dev": true, - "peer": true, - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", - "dev": true, - "peer": true - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", - "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", - "dev": true, - "peer": true, - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.12.1" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", - "dev": true, - "peer": true, - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", - "dev": true, - "peer": true, - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", - "dev": true, - "peer": true - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", - "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", - "dev": true, - "peer": true, - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-opt": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1", - "@webassemblyjs/wast-printer": "1.12.1" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", - "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", - "dev": true, - "peer": true, - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", - "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", - "dev": true, - "peer": true, - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", - "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", - "dev": true, - "peer": true, - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", - "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", - "dev": true, - "peer": true, - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true, - "peer": true - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true, - "peer": true - }, - "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", - "dev": true, - "peer": true, - "peerDependencies": { - "acorn": "^8" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "peer": true, - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/aria-query": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", - "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", - "dev": true, - "dependencies": { - "dequal": "^2.0.3" - } - }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-includes": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", - "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/array.prototype.find": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/array.prototype.find/-/array.prototype.find-2.2.3.tgz", - "integrity": "sha512-fO/ORdOELvjbbeIfZfzrXFMhYHGofRGqd+am9zm3tZ4GlJINj/pA2eITyfd65Vg6+ZbHd/Cys7stpoRSWtQFdA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", - "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/assertion-error": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dev": true, - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/babel-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", - "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", - "dev": true, - "dependencies": { - "@jest/transform": "^29.7.0", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.6.3", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.8.0" - } - }, - "node_modules/babel-jest/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/babel-jest/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/babel-jest/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/babel-jest/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/babel-jest/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-jest/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-jest-hoist": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", - "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", - "dev": true, - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/babel-plugin-module-resolver": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-5.0.2.tgz", - "integrity": "sha512-9KtaCazHee2xc0ibfqsDeamwDps6FZNo5S0Q81dUqEuFzVwPhcT4J5jOqIVvgCA3Q/wO9hKYxN/Ds3tIsp5ygg==", - "dev": true, - "dependencies": { - "find-babel-config": "^2.1.1", - "glob": "^9.3.3", - "pkg-up": "^3.1.0", - "reselect": "^4.1.7", - "resolve": "^1.22.8" - } - }, - "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", - "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.2", - "semver": "^6.3.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", - "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", - "dev": true, - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.1", - "core-js-compat": "^3.36.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", - "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", - "dev": true, - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dev": true, - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-preset-jest": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", - "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", - "dev": true, - "dependencies": { - "babel-plugin-jest-hoist": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true - }, - "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "dependencies": { - "node-int64": "^0.4.0" - } - }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cacheable": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-1.8.9.tgz", - "integrity": "sha512-FicwAUyWnrtnd4QqYAoRlNs44/a1jTL7XDKqm5gJ90wz1DQPlC7U2Rd1Tydpv+E7WAr4sQHuw8Q8M3nZMAyecQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "hookified": "^1.7.1", - "keyv": "^5.3.1" - } - }, - "node_modules/cacheable/node_modules/keyv": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.3.2.tgz", - "integrity": "sha512-Lji2XRxqqa5Wg+CHLVfFKBImfJZ4pCSccu9eVWK6w4c2SDFLd8JAn1zqTuSFnsxb7ope6rMsnIHfp+eBbRBRZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@keyv/serialize": "^1.0.3" - } - }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dev": true, - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001618", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001618.tgz", - "integrity": "sha512-p407+D1tIkDvsEAPS22lJxLQQaG8OTBEqo0KhzfABGk0TU4juBNDSfH0hyAp/HRyx+M8L17z/ltyhxh27FTfQg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] - }, - "node_modules/chai": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.0.tgz", - "integrity": "sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "assertion-error": "^2.0.1", - "check-error": "^2.1.1", - "deep-eql": "^5.0.1", - "loupe": "^3.1.0", - "pathval": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/check-error": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", - "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 16" - } - }, - "node_modules/chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-spinners": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", - "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/colord": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", - "dev": true, - "license": "MIT" - }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true, - "peer": true - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/confusing-browser-globals": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", - "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", - "dev": true - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, - "node_modules/core-js": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", - "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", - "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", - "dev": true, - "hasInstallScript": true - }, - "node_modules/core-js-compat": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", - "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", - "dev": true, - "dependencies": { - "browserslist": "^4.23.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/cosmiconfig": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", - "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "env-paths": "^2.2.1", - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/cosmiconfig/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/cosmiconfig/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/css-functions-list": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.3.tgz", - "integrity": "sha512-IQOkD3hbR5KrN93MtcYuad6YPuTSUhntLHDuLEbFWE+ff2/XSZNdZG+LcbbIW5AXKg/WFIfYItIzVoHngHXZzA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12 || >=16" - } - }, - "node_modules/css-tree": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", - "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "mdn-data": "2.12.2", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" - } - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true, - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "dev": true, - "license": "MIT" - }, - "node_modules/data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-eql": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", - "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/defaults": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", - "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", - "dev": true, - "dependencies": { - "clone": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "dev": true, - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] - }, - "node_modules/domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "dev": true, - "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", - "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", - "dev": true, - "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/dotenv": { - "version": "16.4.7", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", - "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==", - "dev": true, - "license": "BSD-2-Clause", - "peer": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.4.767", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.767.tgz", - "integrity": "sha512-nzzHfmQqBss7CE3apQHkHjXW77+8w3ubGCIoEijKCJebPufREaFETgGXWTkh32t259F3Kcq+R8MZdFdOJROgYw==", - "dev": true - }, - "node_modules/emoji-regex": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", - "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", - "dev": true - }, - "node_modules/enhanced-resolve": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-0.9.1.tgz", - "integrity": "sha512-kxpoMgrdtkXZ5h0SeraBS1iRntpTpQ3R8ussdb38+UAFnMGX5DDyJXePm+OCHOcoXvHDw7mc2erbJBpDnl7TPw==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.2.0", - "tapable": "^0.1.8" - }, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true, - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-module-lexer": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", - "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", - "dev": true, - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.2.4", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", - "dev": true, - "dependencies": { - "hasown": "^2.0.0" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/esbuild": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz", - "integrity": "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "peer": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.1", - "@esbuild/android-arm": "0.25.1", - "@esbuild/android-arm64": "0.25.1", - "@esbuild/android-x64": "0.25.1", - "@esbuild/darwin-arm64": "0.25.1", - "@esbuild/darwin-x64": "0.25.1", - "@esbuild/freebsd-arm64": "0.25.1", - "@esbuild/freebsd-x64": "0.25.1", - "@esbuild/linux-arm": "0.25.1", - "@esbuild/linux-arm64": "0.25.1", - "@esbuild/linux-ia32": "0.25.1", - "@esbuild/linux-loong64": "0.25.1", - "@esbuild/linux-mips64el": "0.25.1", - "@esbuild/linux-ppc64": "0.25.1", - "@esbuild/linux-riscv64": "0.25.1", - "@esbuild/linux-s390x": "0.25.1", - "@esbuild/linux-x64": "0.25.1", - "@esbuild/netbsd-arm64": "0.25.1", - "@esbuild/netbsd-x64": "0.25.1", - "@esbuild/openbsd-arm64": "0.25.1", - "@esbuild/openbsd-x64": "0.25.1", - "@esbuild/sunos-x64": "0.25.1", - "@esbuild/win32-arm64": "0.25.1", - "@esbuild/win32-ia32": "0.25.1", - "@esbuild/win32-x64": "0.25.1" - } - }, - "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-airbnb-base": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz", - "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", - "dev": true, - "dependencies": { - "confusing-browser-globals": "^1.0.10", - "object.assign": "^4.1.2", - "object.entries": "^1.1.5", - "semver": "^6.3.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "peerDependencies": { - "eslint": "^7.32.0 || ^8.2.0", - "eslint-plugin-import": "^2.25.2" - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-import-resolver-webpack": { - "version": "0.13.8", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-webpack/-/eslint-import-resolver-webpack-0.13.8.tgz", - "integrity": "sha512-Y7WIaXWV+Q21Rz/PJgUxiW/FTBOWmU8NTLdz+nz9mMoiz5vAev/fOaQxwD7qRzTfE3HSm1qsxZ5uRd7eX+VEtA==", - "dev": true, - "dependencies": { - "array.prototype.find": "^2.2.2", - "debug": "^3.2.7", - "enhanced-resolve": "^0.9.1", - "find-root": "^1.1.0", - "hasown": "^2.0.0", - "interpret": "^1.4.0", - "is-core-module": "^2.13.1", - "is-regex": "^1.1.4", - "lodash": "^4.17.21", - "resolve": "^2.0.0-next.5", - "semver": "^5.7.2" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "eslint-plugin-import": ">=1.4.0", - "webpack": ">=1.11.0" - } - }, - "node_modules/eslint-import-resolver-webpack/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-import-resolver-webpack/node_modules/resolve": { - "version": "2.0.0-next.5", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", - "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", - "dev": true, - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/eslint-import-resolver-webpack/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/eslint-module-utils": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", - "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", - "dev": true, - "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-file-progress": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-file-progress/-/eslint-plugin-file-progress-1.4.0.tgz", - "integrity": "sha512-MQiq8GGfPc8stuECBktL03CAUu91+kZyufsVjoAEzC7Y4ipAY9M3xB3YYCt7Xv0C5O5t47wlAkqaxnX6LO7DBg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.2", - "ora": "^5.4.1" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" - } - }, - "node_modules/eslint-plugin-file-progress/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/eslint-plugin-file-progress/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/eslint-plugin-file-progress/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/eslint-plugin-file-progress/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/eslint-plugin-file-progress/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint-plugin-file-progress/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint-plugin-filename-rules": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-filename-rules/-/eslint-plugin-filename-rules-1.3.1.tgz", - "integrity": "sha512-kBMxGFvK3QrRBHMurhFSNa+PFdszezVtBV6egg39TDzlj6D4jL3Xx6oyNjm5xE4C+TdQUBzWwymHJHBPyxOreA==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/eslint-plugin-html": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-8.1.1.tgz", - "integrity": "sha512-6qmlJsc40D2m3Dn9oEH+0PAOkJhxVu0f5sVItqpCE0YWgYnyP4xCjBc3UWTHaJcY9ARkWOLIIuXLq0ndRnQOHw==", - "dev": true, - "dependencies": { - "htmlparser2": "^9.1.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", - "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", - "dev": true, - "peer": true, - "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", - "semver": "^6.3.1", - "tsconfig-paths": "^3.15.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "node_modules/eslint-plugin-import/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "peer": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "peer": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "peer": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eslint-plugin-inclusive-language": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-inclusive-language/-/eslint-plugin-inclusive-language-2.2.1.tgz", - "integrity": "sha512-RL6avDWXCS0Dcp9axhvHRUp65qG07qjOrh6J4BNNahPvRY3PuYGnAd0H1strZ9cob79JiEW4Bq0j3gEuzbv0/A==", - "dev": true, - "dependencies": { - "humps": "^2.0.1" - } - }, - "node_modules/eslint-plugin-jest": { - "version": "28.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.5.0.tgz", - "integrity": "sha512-6np6DGdmNq/eBbA7HOUNV8fkfL86PYwBfwyb8n23FXgJNTR8+ot3smRHjza9LGsBBZRypK3qyF79vMjohIL8eQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/utils": "^6.0.0 || ^7.0.0" - }, - "engines": { - "node": "^16.10.0 || ^18.12.0 || >=20.0.0" - }, - "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^6.0.0 || ^7.0.0", - "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0", - "jest": "*" - }, - "peerDependenciesMeta": { - "@typescript-eslint/eslint-plugin": { - "optional": true - }, - "jest": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-plugin-rules": { - "resolved": "../../../../../../../src/Administration/Resources/app/administration/eslint-rules/plugin-rules", - "link": true - }, - "node_modules/eslint-plugin-simple-import-sort": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-12.1.0.tgz", - "integrity": "sha512-Y2fqAfC11TcG/WP3TrI1Gi3p3nc8XJyEOJYHyEPEGI/UAgNx6akxxlX74p7SbAQdLcgASKhj8M0GKvH3vq/+ig==", - "dev": true, - "peerDependencies": { - "eslint": ">=5.0.0" - } - }, - "node_modules/eslint-plugin-sw-core-rules": { - "resolved": "../../../../../../../src/Administration/Resources/app/administration/eslint-rules/core-rules", - "link": true - }, - "node_modules/eslint-plugin-sw-deprecation-rules": { - "resolved": "../../../../../../../src/Administration/Resources/app/administration/eslint-rules/deprecation-rules", - "link": true - }, - "node_modules/eslint-plugin-sw-test-rules": { - "resolved": "../../../../../../../src/Administration/Resources/app/administration/eslint-rules/test-rules", - "link": true - }, - "node_modules/eslint-plugin-twig-vue": { - "resolved": "../../../../../../../src/Administration/Resources/app/administration/twigVuePlugin", - "link": true - }, - "node_modules/eslint-plugin-vue": { - "version": "9.26.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.26.0.tgz", - "integrity": "sha512-eTvlxXgd4ijE1cdur850G6KalZqk65k1JKoOI2d1kT3hr8sPD07j1q98FRFdNnpxBELGPWxZmInxeHGF/GxtqQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "globals": "^13.24.0", - "natural-compare": "^1.4.0", - "nth-check": "^2.1.1", - "postcss-selector-parser": "^6.0.15", - "semver": "^7.6.0", - "vue-eslint-parser": "^9.4.2", - "xml-name-validator": "^4.0.0" - }, - "engines": { - "node": "^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" - } - }, - "node_modules/eslint-plugin-vue/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint-plugin-vue/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint-plugin-vuejs-accessibility": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vuejs-accessibility/-/eslint-plugin-vuejs-accessibility-2.3.0.tgz", - "integrity": "sha512-zQ6IzK+3obZzPsjeVUeL3xAUlMHXZgRZ8vgXvQAmoZVbsp1xZe6UwXIKUFIim5h3tq/7bOLgei09GoBjJQs+Cw==", - "dev": true, - "dependencies": { - "aria-query": "^5.3.0", - "emoji-regex": "^10.0.0", - "vue-eslint-parser": "^9.0.1" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/eslint/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/eslint/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/eslint/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/eslint/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/eslint/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eslint/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@types/estree": "^1.0.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/expect-type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.0.tgz", - "integrity": "sha512-80F22aiJ3GLyVnS/B3HzgR6RelZVumzj9jkL0Rhz4h0xYbNW9PjlQz5h3J/SShErbXBc295vseR4/MIbVmUbeA==", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fast-uri": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", - "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/fastest-levenshtein": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", - "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4.9.1" - } - }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "dev": true, - "dependencies": { - "bser": "2.1.1" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-babel-config": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-2.1.1.tgz", - "integrity": "sha512-5Ji+EAysHGe1OipH7GN4qDjok5Z1uw5KAwDCbicU/4wyTZY7CqOCzcWbG7J5ad9mazq67k89fXlbc1MuIfl9uA==", - "dev": true, - "dependencies": { - "json5": "^2.2.3", - "path-exists": "^4.0.0" - } - }, - "node_modules/find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/find-root": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", - "dev": true - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", - "dev": true, - "license": "ISC" - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-east-asian-width": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz", - "integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dev": true, - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/glob": { - "version": "9.3.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", - "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "minimatch": "^8.0.2", - "minipass": "^4.2.4", - "path-scurry": "^1.6.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true, - "peer": true - }, - "node_modules/glob/node_modules/minimatch": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", - "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "global-prefix": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/global-prefix/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "dev": true, - "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globjoin": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", - "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", - "dev": true, - "license": "MIT" - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "node_modules/has": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", - "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", - "dev": true, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/hookified": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.8.1.tgz", - "integrity": "sha512-GrO2l93P8xCWBSTBX9l2BxI78VU/MAAYag+pG8curS3aBGy0++ZlxrQ7PdUOUVMbn5BwkGb6+eRrnf43ipnFEA==", - "dev": true, - "license": "MIT" - }, - "node_modules/html-tags": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", - "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/htmlparser2": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", - "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", - "dev": true, - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.1.0", - "entities": "^4.5.0" - } - }, - "node_modules/humps": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/humps/-/humps-2.0.1.tgz", - "integrity": "sha512-E0eIbrFWUhwfXJmsbdjRQFQPrl5pTEoKlz163j1mTqqUnU9PgR4AgB8AIITzuB3vLBdxZXyZ9TDIrwB2OASz4g==", - "dev": true - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-fresh/node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true, - "license": "ISC" - }, - "node_modules/internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", - "dev": true, - "dependencies": { - "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true, - "license": "MIT" - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dev": true, - "dependencies": { - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", - "dev": true, - "dependencies": { - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-interactive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "dev": true, - "dependencies": { - "which-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" + "has-symbols": "^1.0.3" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", - "dev": true, - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-haste-map": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", - "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", - "@types/graceful-fs": "^4.1.3", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "micromatch": "^4.0.4", - "walker": "^1.0.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "function-bind": "^1.1.2" }, - "optionalDependencies": { - "fsevents": "^2.3.2" - } - }, - "node_modules/jest-regex-util": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", - "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", - "dev": true, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">= 0.4" } }, - "node_modules/jest-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", "dev": true, + "license": "ISC", "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" + "lru-cache": "^6.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=10" } }, - "node_modules/jest-util/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/html-tags": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, + "license": "MIT", "engines": { "node": ">=8" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-util/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" } }, - "node_modules/jest-util/node_modules/color-convert": { + "node_modules/humps": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "resolved": "https://registry.npmjs.org/humps/-/humps-2.0.1.tgz", + "integrity": "sha512-E0eIbrFWUhwfXJmsbdjRQFQPrl5pTEoKlz163j1mTqqUnU9PgR4AgB8AIITzuB3vLBdxZXyZ9TDIrwB2OASz4g==", "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-util/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "license": "MIT" }, - "node_modules/jest-util/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">= 4" } }, - "node_modules/jest-util/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, + "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/jest-worker": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", - "dev": true, - "dependencies": { - "@types/node": "*", - "jest-util": "^29.7.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" + "node": ">=6" }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-worker/node_modules/has-flag": { + "node_modules/import-lazy": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, + "license": "MIT", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "node": ">=0.8.19" } }, - "node_modules/js-tokens": { + "node_modules/indent-string": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true, + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/known-css-properties": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.35.0.tgz", - "integrity": "sha512-a/RAk2BfKk+WFGhhOCAYqSiFLc34k8Mt/6NWRI4joER0EYUzXIcFivjjnoD3+XU1DggLn/tZc3DOAgke7l8a4A==", - "dev": true, - "license": "MIT" - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, + "license": "ISC", "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" + "once": "^1.3.0", + "wrappy": "1" } }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true, - "license": "MIT" + "license": "ISC" }, - "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true, - "peer": true, - "engines": { - "node": ">=6.11.5" - } + "license": "ISC" }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", "dev": true, + "license": "MIT", "dependencies": { - "p-locate": "^4.1.0" + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" }, "engines": { - "node": ">=8" + "node": ">= 0.4" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true, - "license": "MIT" - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", "dev": true, + "license": "MIT", "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/log-symbols/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", "dev": true, + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" }, "engines": { - "node": ">=8" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/log-symbols/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", "dev": true, + "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "has-bigints": "^1.0.2" }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/log-symbols/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", "dev": true, + "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { - "node": ">=7.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/log-symbols/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/log-symbols/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/log-symbols/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "dev": true, + "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "hasown": "^2.0.2" }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/loupe": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.3.tgz", - "integrity": "sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==", + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", "dev": true, "license": "MIT", - "peer": true - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, "dependencies": { - "yallist": "^3.0.2" + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/magic-string": { - "version": "0.30.17", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", - "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, - "node_modules/make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" }, "engines": { - "node": ">=6" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, - "dependencies": { - "tmpl": "1.0.5" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/mathml-tag-names": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", - "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/mdn-data": { - "version": "2.12.2", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", - "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", - "dev": true, - "license": "CC0-1.0" - }, - "node_modules/memory-fs": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.2.0.tgz", - "integrity": "sha512-+y4mDxU4rvXXu5UDSGCGNiesFmwCHuefGMoPCO1WYucNYj7DsLqrFaa2fXVI0H+NNiPTwwzKwspn9yTZqUGqng==", - "dev": true - }, - "node_modules/meow": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", - "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", "dev": true, "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, "engines": { - "node": ">=18" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, + "license": "MIT", "engines": { - "node": ">= 8" + "node": ">=8" } }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", "dev": true, "license": "MIT", "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" }, "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 0.6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { - "mime-db": "1.52.0" + "is-extglob": "^2.1.1" }, "engines": { - "node": ">= 0.6" + "node": ">=0.10.0" } }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", "dev": true, + "license": "MIT", "engines": { - "node": ">=6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/mimic-function": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", - "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true, "license": "MIT", - "peer": true, "engines": { - "node": ">=18" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", "dev": true, + "license": "MIT", "dependencies": { - "brace-expansion": "^2.0.1" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">= 0.4" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/minipass": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", - "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "node": ">=0.10.0" } }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true, - "peer": true - }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true - }, - "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", "dev": true, + "license": "MIT", "dependencies": { - "boolbase": "^1.0.0" + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" + "call-bound": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -8608,31 +3256,33 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.entries": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", - "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.fromentries": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", - "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -8641,31 +3291,28 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.groupby": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", - "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2" + "which-typed-array": "^1.1.16" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.values": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", - "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -8673,652 +3320,604 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", "dev": true, + "license": "MIT", "dependencies": { - "mimic-fn": "^2.1.0" + "call-bound": "^1.0.3" }, "engines": { - "node": ">=6" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ora": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", "dev": true, + "license": "MIT", "dependencies": { - "bl": "^4.1.0", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.5.0", - "is-interactive": "^1.0.0", - "is-unicode-supported": "^0.1.0", - "log-symbols": "^4.1.0", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ora/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" + "argparse": "^2.0.1" }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/ora/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, + "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" + "minimist": "^1.2.0" }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "bin": { + "json5": "lib/cli.js" } }, - "node_modules/ora/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, + "license": "MIT", "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" + "json-buffer": "3.0.1" } }, - "node_modules/ora/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/ora/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/ora/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/known-css-properties": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.26.0.tgz", + "integrity": "sha512-5FZRzrZzNTBruuurWpvZnvP9pum+fe0HcK8z/ooo+U+Hmp4vtbyp1/QDsqmufirXy4egGzbaH/y2uCZf+6W5Kg==", + "dev": true, + "license": "MIT" + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" }, "engines": { - "node": ">=8" + "node": ">= 0.8.0" } }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, + "license": "MIT", "dependencies": { - "p-try": "^2.0.0" + "p-locate": "^5.0.0" }, "engines": { - "node": ">=6" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } + "license": "MIT" }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true, - "engines": { - "node": ">=6" - } + "license": "MIT" }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, + "license": "ISC", "dependencies": { - "callsites": "^3.0.0" + "yallist": "^4.0.0" }, "engines": { - "node": ">=6" + "node": ">=10" } }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "@jridgewell/sourcemap-codec": "^1.5.5" } }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "dev": true, + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "node_modules/mathml-tag-names": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", + "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", "dev": true, - "engines": { - "node": ">=8" + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "node_modules/meow": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", + "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", "dev": true, + "license": "MIT", "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize": "^1.2.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" }, "engines": { - "node": ">=16 || 14 >=14.18" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", - "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", + "node_modules/meow/node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { - "node": "14 || >=16.14" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/path-scurry/node_modules/minipass": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.1.tgz", - "integrity": "sha512-UZ7eQ+h8ywIRAW1hIEl2AqdwzJucU/Kp59+8kkZeSvafXhZjul247BvIJjEVFVeON6d7lM46XX1HXCduKAS8VA==", + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, + "license": "MIT", "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">= 8" } }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, "engines": { - "node": ">=8" + "node": ">=8.6" } }, - "node_modules/pathe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/pathval": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", - "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", "dev": true, "license": "MIT", - "peer": true, "engines": { - "node": ">= 14.16" + "node": ">=4" } }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, "engines": { - "node": ">=8.6" + "node": ">=16 || 14 >=14.17" }, "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "engines": { - "node": ">=6" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, - "engines": { - "node": ">= 6" + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", "dev": true, + "license": "MIT", "dependencies": { - "find-up": "^3.0.0" + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" }, "engines": { - "node": ">=6" + "node": ">= 6" } }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true, - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } + "license": "MIT" }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "dev": true, - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" }, "engines": { - "node": ">=6" + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "node_modules/nanospinner": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/nanospinner/-/nanospinner-1.2.2.tgz", + "integrity": "sha512-Zt/AmG6qRU3e+WnzGGLuMCEAO/dAu45stNbHY223tUxldaDAeE+FxSPsd9Q+j+paejmm0ZbrNVs5Sraqy3dRxA==", "dev": true, + "license": "MIT", "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" + "picocolors": "^1.1.1" } }, - "node_modules/pkg-dir/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true, - "engines": { - "node": ">=4" - } + "license": "MIT" }, - "node_modules/pkg-up": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "find-up": "^3.0.0" + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" }, "engines": { - "node": ">=8" + "node": ">=10" } }, - "node_modules/pkg-up/node_modules/find-up": { + "node_modules/normalize-path": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, - "dependencies": { - "locate-path": "^3.0.0" - }, + "license": "MIT", "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, - "node_modules/pkg-up/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "boolbase": "^1.0.0" }, - "engines": { - "node": ">=6" + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" } }, - "node_modules/pkg-up/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "dev": true, - "dependencies": { - "p-limit": "^2.0.0" - }, + "license": "MIT", "engines": { - "node": ">=6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/pkg-up/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, + "license": "MIT", "engines": { - "node": ">=4" + "node": ">= 0.4" } }, - "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/postcss": { - "version": "8.5.3", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", - "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", + "node_modules/object.entries": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.8", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.1" }, "engines": { - "node": "^10 || ^12 || >=14" + "node": ">= 0.4" } }, - "node_modules/postcss-resolve-nested-selector": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.6.tgz", - "integrity": "sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw==", - "dev": true, - "license": "MIT" - }, - "node_modules/postcss-safe-parser": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.1.tgz", - "integrity": "sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==", + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss-safe-parser" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, "engines": { - "node": ">=18.0" + "node": ">= 0.4" }, - "peerDependencies": { - "postcss": "^8.4.31" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/postcss-selector-parser": { - "version": "6.0.16", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz", - "integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==", + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", "dev": true, + "license": "MIT", "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" }, "engines": { - "node": ">=4" + "node": ">= 0.4" } }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/prelude-ls": { + "node_modules/object.values": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "peer": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", "dev": true, + "license": "MIT", "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { - "node": ">= 6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true - }, - "node_modules/regenerate-unicode-properties": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", - "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, + "license": "ISC", "dependencies": { - "regenerate": "^1.4.2" - }, - "engines": { - "node": ">=4" + "wrappy": "1" } }, - "node_modules/regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "dev": true - }, - "node_modules/regenerator-transform": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", - "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/runtime": "^7.8.4" + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" } }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", - "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -9327,589 +3926,557 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/regexpu-core": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", - "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/regjsgen": "^0.8.0", - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsparser": "^0.9.1", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" + "yocto-queue": "^0.1.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "license": "MIT", "dependencies": { - "jsesc": "~0.5.0" + "p-limit": "^3.0.2" }, - "bin": { - "regjsparser": "bin/parser" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, - "bin": { - "jsesc": "bin/jsesc" + "license": "MIT", + "engines": { + "node": ">=6" } }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, - "node_modules/reselect": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz", - "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==", - "dev": true - }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, + "license": "MIT", "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" }, - "bin": { - "resolve": "bin/resolve" + "engines": { + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "license": "MIT", "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } + "license": "MIT" }, - "node_modules/rimraf/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "license": "MIT", + "engines": { + "node": ">=8" } }, - "node_modules/rimraf/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } + "license": "ISC" }, - "node_modules/rimraf/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, + "license": "MIT", "engines": { - "node": "*" + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/rollup": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.37.0.tgz", - "integrity": "sha512-iAtQy/L4QFU+rTJ1YUjXqJOJzuwEghqWzCEYD2FEghT7Gsy1VdABntrO4CLopA5IkflTyqNiLNwPcOJ3S7UKLg==", + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "@types/estree": "1.0.6" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.37.0", - "@rollup/rollup-android-arm64": "4.37.0", - "@rollup/rollup-darwin-arm64": "4.37.0", - "@rollup/rollup-darwin-x64": "4.37.0", - "@rollup/rollup-freebsd-arm64": "4.37.0", - "@rollup/rollup-freebsd-x64": "4.37.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.37.0", - "@rollup/rollup-linux-arm-musleabihf": "4.37.0", - "@rollup/rollup-linux-arm64-gnu": "4.37.0", - "@rollup/rollup-linux-arm64-musl": "4.37.0", - "@rollup/rollup-linux-loongarch64-gnu": "4.37.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.37.0", - "@rollup/rollup-linux-riscv64-gnu": "4.37.0", - "@rollup/rollup-linux-riscv64-musl": "4.37.0", - "@rollup/rollup-linux-s390x-gnu": "4.37.0", - "@rollup/rollup-linux-x64-gnu": "4.37.0", - "@rollup/rollup-linux-x64-musl": "4.37.0", - "@rollup/rollup-win32-arm64-msvc": "4.37.0", - "@rollup/rollup-win32-ia32-msvc": "4.37.0", - "@rollup/rollup-win32-x64-msvc": "4.37.0", - "fsevents": "~2.3.2" + "engines": { + "node": ">= 0.4" } }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", "dev": true, "funding": [ { - "type": "github", - "url": "https://github.com/sponsors/feross" + "type": "opencollective", + "url": "https://opencollective.com/postcss/" }, { - "type": "patreon", - "url": "https://www.patreon.com/feross" + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" }, { - "type": "consulting", - "url": "https://feross.org/support" + "type": "github", + "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "queue-microtask": "^1.2.2" + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" } }, - "node_modules/safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "node_modules/postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, + "license": "MIT" + }, + "node_modules/postcss-resolve-nested-selector": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.6.tgz", + "integrity": "sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw==", + "dev": true, + "license": "MIT" + }, + "node_modules/postcss-safe-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", + "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=0.4" + "node": ">=12.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.3.3" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "node_modules/postcss-scss": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.9.tgz", + "integrity": "sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==", "dev": true, "funding": [ { - "type": "github", - "url": "https://github.com/sponsors/feross" + "type": "opencollective", + "url": "https://opencollective.com/postcss/" }, { - "type": "patreon", - "url": "https://www.patreon.com/feross" + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss-scss" }, { - "type": "consulting", - "url": "https://feross.org/support" + "type": "github", + "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "MIT", + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.4.29" + } }, - "node_modules/safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-regex": "^1.1.4" + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" } }, - "node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "node_modules/prettier": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", + "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", "dev": true, - "peer": true, - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" }, "engines": { - "node": ">= 10.13.0" + "node": ">=14" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "node_modules/prettier-plugin-multiline-arrays": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/prettier-plugin-multiline-arrays/-/prettier-plugin-multiline-arrays-3.0.6.tgz", + "integrity": "sha512-FrWVa7MoDQo9b5XoLPrqIDClb0k+O8wOIsIr1DutRXhcerLY8PfIe/yYeTVD/vpRISkSXCBEYmj5Voe0wb5dEQ==", "dev": true, - "bin": { - "semver": "bin/semver.js" + "license": "(MIT or CC0 1.0)", + "dependencies": { + "@augment-vir/common": "^28.1.0", + "proxy-vir": "^1.0.0" + }, + "peerDependencies": { + "prettier": ">=3.0.0" } }, - "node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "node_modules/proxy-vir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/proxy-vir/-/proxy-vir-1.0.0.tgz", + "integrity": "sha512-WV1gkBxUOwLSz0Bn09tisIqLK7leAqtFm/474t3L0hQKJw7/gdrkGcWw0/OT1PhSy+TDS6swfq7Niuoq3XJhkQ==", "dev": true, - "peer": true, + "license": "(MIT or CC0 1.0)", "dependencies": { - "randombytes": "^2.1.0" + "@augment-vir/common": "^23.3.4" } }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "node_modules/proxy-vir/node_modules/@augment-vir/common": { + "version": "23.4.0", + "resolved": "https://registry.npmjs.org/@augment-vir/common/-/common-23.4.0.tgz", + "integrity": "sha512-QIrJ1doD00TNbOzeVrk9KgPTzRlIjayxERnhtbQjK/AFPj5yElcB03GbnGdQZPzws/R+5gfMM5cZiH7QyBP+Kg==", "dev": true, + "license": "MIT", "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" + "browser-or-node": "^2.1.1", + "run-time-assertions": "^1.0.0", + "type-fest": "^4.10.2" } }, - "node_modules/set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "node_modules/proxy-vir/node_modules/browser-or-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/browser-or-node/-/browser-or-node-2.1.1.tgz", + "integrity": "sha512-8CVjaLJGuSKMVTxJ2DpBl5XnlNDiT4cQFeuCJJrvJmts9YrTZDizTX7PjC2s6W4x+MBGZeEY6dGMrF04/6Hgqg==", "dev": true, - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - }, + "license": "MIT" + }, + "node_modules/proxy-vir/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">= 0.4" + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, - "dependencies": { - "kind-of": "^6.0.2" - }, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=6" } }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", "dev": true, + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, "engines": { "node": ">=8" } }, - "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" }, "engines": { - "node": ">= 0.4" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/siginfo": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", - "dev": true, - "license": "ISC", - "peer": true - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, "engines": { "node": ">=8" } }, - "node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" + "p-locate": "^4.1.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" + "node": ">=8" } }, - "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "p-try": "^2.0.0" }, "engines": { - "node": ">=8" + "node": ">=6" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/slice-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "p-limit": "^2.2.0" }, "engines": { - "node": ">=7.0.0" + "node": ">=8" } }, - "node_modules/slice-ansi/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT" - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } + "license": "ISC" }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" } }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "node_modules/stackback": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/std-env": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.1.tgz", - "integrity": "sha512-vj5lIj3Mwf9D79hBkltk5qmkFI+biIKWS2IBxEyEU3AX1tUf7AoL8nSazCOiiqQsGKIq01SClsKEzweu34uwvA==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/stdin-discarder": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz", - "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==", + "node_modules/read-pkg/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "license": "ISC", + "bin": { + "semver": "bin/semver" } }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", "dev": true, - "dependencies": { - "safe-buffer": "~5.2.0" + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" } }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", "dev": true, "license": "MIT", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" }, "engines": { "node": ">=8" } }, - "node_modules/string-width/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" }, "engines": { "node": ">= 0.4" @@ -9918,29 +4485,19 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -9949,290 +4506,307 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, "engines": { - "node": ">=4" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=4" } }, - "node_modules/stylelint": { - "version": "16.16.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.16.0.tgz", - "integrity": "sha512-40X5UOb/0CEFnZVEHyN260HlSSUxPES+arrUphOumGWgXERHfwCD0kNBVILgQSij8iliYVwlc0V7M5bcLP9vPg==", + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/stylelint" - }, - { - "type": "github", - "url": "https://github.com/sponsors/stylelint" - } - ], "license": "MIT", - "dependencies": { - "@csstools/css-parser-algorithms": "^3.0.4", - "@csstools/css-tokenizer": "^3.0.3", - "@csstools/media-query-list-parser": "^4.0.2", - "@csstools/selector-specificity": "^5.0.0", - "@dual-bundle/import-meta-resolve": "^4.1.0", - "balanced-match": "^2.0.0", - "colord": "^2.9.3", - "cosmiconfig": "^9.0.0", - "css-functions-list": "^3.2.3", - "css-tree": "^3.1.0", - "debug": "^4.3.7", - "fast-glob": "^3.3.3", - "fastest-levenshtein": "^1.0.16", - "file-entry-cache": "^10.0.7", - "global-modules": "^2.0.0", - "globby": "^11.1.0", - "globjoin": "^0.1.4", - "html-tags": "^3.3.1", - "ignore": "^7.0.3", - "imurmurhash": "^0.1.4", - "is-plain-object": "^5.0.0", - "known-css-properties": "^0.35.0", - "mathml-tag-names": "^2.1.3", - "meow": "^13.2.0", - "micromatch": "^4.0.8", - "normalize-path": "^3.0.0", - "picocolors": "^1.1.1", - "postcss": "^8.5.3", - "postcss-resolve-nested-selector": "^0.1.6", - "postcss-safe-parser": "^7.0.1", - "postcss-selector-parser": "^7.1.0", - "postcss-value-parser": "^4.2.0", - "resolve-from": "^5.0.0", - "string-width": "^4.2.3", - "supports-hyperlinks": "^3.2.0", - "svg-tags": "^1.0.0", - "table": "^6.9.0", - "write-file-atomic": "^5.0.1" - }, - "bin": { - "stylelint": "bin/stylelint.mjs" - }, "engines": { - "node": ">=18.12.0" + "iojs": ">=1.0.0", + "node": ">=0.10.0" } }, - "node_modules/stylelint-define-config": { - "version": "16.15.0", - "resolved": "https://registry.npmjs.org/stylelint-define-config/-/stylelint-define-config-16.15.0.tgz", - "integrity": "sha512-nzHX9ZpI/k4A7izGYPS79xLAf2HyGvYkk/UXMgsQ7ZQEvkOZpQt4Aca4Qn5DYqNmWnqNlW5E3wK+qUmdR3vdxg==", + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "csstype": "^3.1.3" + "glob": "^7.1.3" }, - "engines": { - "node": ">=18.0.0", - "npm": ">=9.0.0", - "pnpm": ">=8.6.0" + "bin": { + "rimraf": "bin.js" }, - "peerDependencies": { - "stylelint": ">=16.0.0" + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/stylelint/node_modules/@csstools/selector-specificity": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", - "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "funding": [ { "type": "github", - "url": "https://github.com/sponsors/csstools" + "url": "https://github.com/sponsors/feross" }, { - "type": "opencollective", - "url": "https://opencollective.com/csstools" + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" } ], - "license": "MIT-0", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss-selector-parser": "^7.0.0" + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" } }, - "node_modules/stylelint/node_modules/balanced-match": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", - "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", - "dev": true, - "license": "MIT" - }, - "node_modules/stylelint/node_modules/file-entry-cache": { - "version": "10.0.7", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-10.0.7.tgz", - "integrity": "sha512-txsf5fu3anp2ff3+gOJJzRImtrtm/oa9tYLN0iTuINZ++EyVR/nRrg2fKYwvG/pXDofcrvvb0scEbX3NyW/COw==", + "node_modules/run-time-assertions": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/run-time-assertions/-/run-time-assertions-1.5.2.tgz", + "integrity": "sha512-ccfwvjGuNU14cSSXLlmPRiqEgMfA7w3J2TViO79zMnzXGvE6FJ0dxnhIQGwe5r/vwySOJ4sqZksexo9wyAlA8g==", + "deprecated": "Use @augment-vir/assert instead.", "dev": true, - "license": "MIT", + "license": "(MIT or CC0 1.0)", "dependencies": { - "flat-cache": "^6.1.7" + "@augment-vir/common": "^29.3.0", + "expect-type": "~0.15.0", + "type-fest": "^4.22.0" } }, - "node_modules/stylelint/node_modules/flat-cache": { - "version": "6.1.7", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.7.tgz", - "integrity": "sha512-qwZ4xf1v1m7Rc9XiORly31YaChvKt6oNVHuqqZcoED/7O+ToyNVGobKsIAopY9ODcWpEDKEBAbrSOCBHtNQvew==", + "node_modules/run-time-assertions/node_modules/@augment-vir/common": { + "version": "29.3.0", + "resolved": "https://registry.npmjs.org/@augment-vir/common/-/common-29.3.0.tgz", + "integrity": "sha512-k3OX35/576thmGUzQUBcCKGarb7ONBfiu07+iV2vxmjl7VoB1rOB0vu8WqgB1ceJq2EMLDPXY18hHpJ9WeTHXQ==", "dev": true, "license": "MIT", "dependencies": { - "cacheable": "^1.8.9", - "flatted": "^3.3.3", - "hookified": "^1.7.1" + "browser-or-node": "^3.0.0", + "run-time-assertions": "^1.5.1", + "type-fest": "^4.21.0" } }, - "node_modules/stylelint/node_modules/ignore": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.3.tgz", - "integrity": "sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA==", + "node_modules/run-time-assertions/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", "dev": true, - "license": "MIT", + "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">= 4" + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/stylelint/node_modules/is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", "dev": true, "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, "engines": { - "node": ">=0.10.0" + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/stylelint/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", "dev": true, "license": "MIT", "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" + "es-errors": "^1.3.0", + "isarray": "^2.0.5" }, "engines": { - "node": ">=4" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/stylelint/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", "dev": true, - "license": "ISC", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, "engines": { - "node": ">=14" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/stylelint/node_modules/write-file-atomic": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", - "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "dev": true, "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">= 0.4" } }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", "dev": true, + "license": "MIT", "dependencies": { - "has-flag": "^3.0.0" + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" }, "engines": { - "node": ">=4" + "node": ">= 0.4" } }, - "node_modules/supports-hyperlinks": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.2.0.tgz", - "integrity": "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==", + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", "dev": true, "license": "MIT", "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" }, "engines": { - "node": ">=14.18" + "node": ">= 0.4" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" }, - "funding": { - "url": "https://github.com/chalk/supports-hyperlinks?sponsor=1" + "engines": { + "node": ">=8" } }, - "node_modules/supports-hyperlinks/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/supports-hyperlinks/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "dev": true, "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/supports-preserve-symlinks-flag": { + "node_modules/side-channel-list": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, "engines": { "node": ">= 0.4" }, @@ -10240,422 +4814,462 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/svg-tags": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", - "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", - "dev": true - }, - "node_modules/table": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz", - "integrity": "sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==", + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", "dependencies": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" }, "engines": { - "node": ">=10.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/table/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", "dev": true, "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/table/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true, - "license": "MIT" + "license": "ISC" }, - "node_modules/tapable": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.1.10.tgz", - "integrity": "sha512-jX8Et4hHg57mug1/079yitEKWGB3LCwoxByLsNim89LABq8NqgiX+6iYVOsq0vX8uJHkU+DZ5fnq95f800bEsQ==", + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, + "license": "MIT", "engines": { - "node": ">=0.6" + "node": ">=8" } }, - "node_modules/terser": { - "version": "5.31.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.0.tgz", - "integrity": "sha512-Q1JFAoUKE5IMfI4Z/lkE/E6+SwgzO+x4tq4v1AyBLRj8VSYvRO6A/rQrPg1yud4g0En9EKI1TvFRF2tQFcoUkg==", + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/terser-webpack-plugin": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", - "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, - "peer": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.20", - "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.26.0" - }, + "license": "BSD-3-Clause", "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "uglify-js": { - "optional": true - } + "node": ">=0.10.0" } }, - "node_modules/terser-webpack-plugin/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "dev": true, - "peer": true, - "engines": { - "node": ">=8" + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" } }, - "node_modules/terser-webpack-plugin/node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" } }, - "node_modules/terser-webpack-plugin/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "node_modules/spdx-license-ids": { + "version": "3.0.22", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", + "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "node": ">= 0.4" } }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8" } }, - "node_modules/test-exclude/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/string-width/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } + "license": "MIT" }, - "node_modules/test-exclude/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", "dev": true, + "license": "MIT", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" }, "engines": { - "node": "*" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/test-exclude/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", "dev": true, + "license": "MIT", "dependencies": { - "brace-expansion": "^1.1.7" + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { - "node": "*" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "node_modules/tinybench": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", - "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", "dev": true, "license": "MIT", - "peer": true + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/tinyexec": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", - "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", - "peer": true + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } }, - "node_modules/tinypool": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz", - "integrity": "sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==", + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true, "license": "MIT", - "peer": true, "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": ">=4" } }, - "node_modules/tinyrainbow": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", - "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "dev": true, "license": "MIT", - "peer": true, + "dependencies": { + "min-indent": "^1.0.0" + }, "engines": { - "node": ">=14.0.0" + "node": ">=8" } }, - "node_modules/tinyspy": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", - "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, "license": "MIT", - "peer": true, "engines": { - "node": ">=14.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "node_modules/style-search": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", + "integrity": "sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==", "dev": true, - "engines": { - "node": ">=4" - } + "license": "ISC" }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "node_modules/stylelint": { + "version": "14.16.1", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.16.1.tgz", + "integrity": "sha512-ErlzR/T3hhbV+a925/gbfc3f3Fep9/bnspMiJPorfGEmcBbXdS+oo6LrVtoUZ/w9fqD6o6k7PtUlCOsCRdjX/A==", "dev": true, "license": "MIT", "dependencies": { - "is-number": "^7.0.0" + "@csstools/selector-specificity": "^2.0.2", + "balanced-match": "^2.0.0", + "colord": "^2.9.3", + "cosmiconfig": "^7.1.0", + "css-functions-list": "^3.1.0", + "debug": "^4.3.4", + "fast-glob": "^3.2.12", + "fastest-levenshtein": "^1.0.16", + "file-entry-cache": "^6.0.1", + "global-modules": "^2.0.0", + "globby": "^11.1.0", + "globjoin": "^0.1.4", + "html-tags": "^3.2.0", + "ignore": "^5.2.1", + "import-lazy": "^4.0.0", + "imurmurhash": "^0.1.4", + "is-plain-object": "^5.0.0", + "known-css-properties": "^0.26.0", + "mathml-tag-names": "^2.1.3", + "meow": "^9.0.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.19", + "postcss-media-query-parser": "^0.2.3", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-safe-parser": "^6.0.0", + "postcss-selector-parser": "^6.0.11", + "postcss-value-parser": "^4.2.0", + "resolve-from": "^5.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "style-search": "^0.1.0", + "supports-hyperlinks": "^2.3.0", + "svg-tags": "^1.0.0", + "table": "^6.8.1", + "v8-compile-cache": "^2.3.0", + "write-file-atomic": "^4.0.2" + }, + "bin": { + "stylelint": "bin/stylelint.js" }, "engines": { - "node": ">=8.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" } }, - "node_modules/ts-api-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "node_modules/stylelint-config-recommended": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-8.0.0.tgz", + "integrity": "sha512-IK6dWvE000+xBv9jbnHOnBq01gt6HGVB2ZTsot+QsMpe82doDQ9hvplxfv4YnpEuUwVGGd9y6nbaAnhrjcxhZQ==", "dev": true, - "engines": { - "node": ">=16" + "license": "MIT", + "peerDependencies": { + "stylelint": "^14.8.0" + } + }, + "node_modules/stylelint-config-recommended-scss": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-7.0.0.tgz", + "integrity": "sha512-rGz1J4rMAyJkvoJW4hZasuQBB7y9KIrShb20l9DVEKKZSEi1HAy0vuNlR8HyCKy/jveb/BdaQFcoiYnmx4HoiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-scss": "^4.0.2", + "stylelint-config-recommended": "^8.0.0", + "stylelint-scss": "^4.0.0" }, "peerDependencies": { - "typescript": ">=4.2.0" + "stylelint": "^14.4.0" } }, - "node_modules/tsconfig-paths": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", - "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "node_modules/stylelint-config-standard": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-26.0.0.tgz", + "integrity": "sha512-hUuB7LaaqM8abvkOO84wh5oYSkpXgTzHu2Zza6e7mY+aOmpNTjoFBRxSLlzY0uAOMWEFx0OMKzr+reG1BUtcqQ==", "dev": true, + "license": "MIT", "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" + "stylelint-config-recommended": "^8.0.0" + }, + "peerDependencies": { + "stylelint": "^14.9.0" } }, - "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "node_modules/stylelint-config-standard-scss": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard-scss/-/stylelint-config-standard-scss-5.0.0.tgz", + "integrity": "sha512-zoXLibojHZYPFjtkc4STZtAJ2yGTq3Bb4MYO0oiyO6f/vNxDKRcSDZYoqN260Gv2eD5niQIr1/kr5SXlFj9kcQ==", "dev": true, + "license": "MIT", "dependencies": { - "minimist": "^1.2.0" + "stylelint-config-recommended-scss": "^7.0.0", + "stylelint-config-standard": "^26.0.0" }, - "bin": { - "json5": "lib/cli.js" + "peerDependencies": { + "stylelint": "^14.9.0" } }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "node_modules/stylelint-junit-formatter": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stylelint-junit-formatter/-/stylelint-junit-formatter-0.2.2.tgz", + "integrity": "sha512-8Yx0sG5vYKf+wBbFKibbuiuydKezBwo2M9svoNYtvYTKvSiMYVhZSvVJh9hMAWeSPImcVP9OwTq+Ku/00j9/Ng==", "dev": true, + "license": "MIT", "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" + "xmlbuilder": "^13.0.2" } }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "node_modules/stylelint-scss": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-4.7.0.tgz", + "integrity": "sha512-TSUgIeS0H3jqDZnby1UO1Qv3poi1N8wUYIJY6D1tuUq2MN3lwp/rITVo0wD+1SWTmRm0tNmGO0b7nKInnqF6Hg==", "dev": true, - "engines": { - "node": ">=10" + "license": "MIT", + "dependencies": { + "postcss-media-query-parser": "^0.2.3", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-selector-parser": "^6.0.11", + "postcss-value-parser": "^4.2.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "stylelint": "^14.5.1 || ^15.0.0" } }, - "node_modules/typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "node_modules/stylelint/node_modules/balanced-match": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", + "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" - }, + "license": "MIT" + }, + "node_modules/stylelint/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=8" } }, - "node_modules/typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" + "has-flag": "^4.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "node_modules/supports-hyperlinks": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", "dev": true, + "license": "MIT", "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" - }, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -10663,479 +5277,326 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "node_modules/svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", + "dev": true + }, + "node_modules/table": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz", + "integrity": "sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==", "dev": true, - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" + "license": "BSD-3-Clause", + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=14.17" + "node": ">=10.0.0" } }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "node_modules/table/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" }, - "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true, - "engines": { - "node": ">=4" - } + "license": "MIT" }, - "node_modules/unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" + "is-number": "^7.0.0" }, "engines": { - "node": ">=4" + "node": ">=8.0" } }, - "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "node_modules/trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", "dev": true, + "license": "MIT", "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/unicode-property-aliases-ecmascript": { + "node_modules/ts-api-utils": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", "dev": true, + "license": "MIT", "engines": { - "node": ">=4" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", - "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" - }, - "bin": { - "update-browserslist-db": "cli.js" + "node": ">=18.12" }, "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" + "typescript": ">=4.8.4" } }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "node_modules/vite": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.3.tgz", - "integrity": "sha512-IzwM54g4y9JA/xAeBPNaDXiBF8Jsgl3VBQ2YQ/wOY6fyW3xMdSoltIV3Bo59DErdqdE6RxUfv8W69DvUorE4Eg==", + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "esbuild": "^0.25.0", - "postcss": "^8.5.3", - "rollup": "^4.30.1" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "jiti": ">=1.21.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.16.0", - "tsx": "^4.8.1", - "yaml": "^2.4.2" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "jiti": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true - } + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" } }, - "node_modules/vite-node": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.9.tgz", - "integrity": "sha512-w3Gdx7jDcuT9cNn9jExXgOyKmf5UOTb6WMHz8LGAm54eS1Elf5OuBhCxl6zJxGhEeIkgsE1WbHuoL0mj/UXqXg==", + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "cac": "^6.7.14", - "debug": "^4.4.0", - "es-module-lexer": "^1.6.0", - "pathe": "^2.0.3", - "vite": "^5.0.0 || ^6.0.0" - }, - "bin": { - "vite-node": "vite-node.mjs" + "prelude-ls": "^1.2.1" }, "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" }, "funding": { - "url": "https://opencollective.com/vitest" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/vitest": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.9.tgz", - "integrity": "sha512-BbcFDqNyBlfSpATmTtXOAOj71RNKDDvjBM/uPfnxxVGrG+FSH2RQIwgeEngTaTkuU/h0ScFvf+tRcKfYXzBybQ==", + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@vitest/expect": "3.0.9", - "@vitest/mocker": "3.0.9", - "@vitest/pretty-format": "^3.0.9", - "@vitest/runner": "3.0.9", - "@vitest/snapshot": "3.0.9", - "@vitest/spy": "3.0.9", - "@vitest/utils": "3.0.9", - "chai": "^5.2.0", - "debug": "^4.4.0", - "expect-type": "^1.1.0", - "magic-string": "^0.30.17", - "pathe": "^2.0.3", - "std-env": "^3.8.0", - "tinybench": "^2.9.0", - "tinyexec": "^0.3.2", - "tinypool": "^1.0.2", - "tinyrainbow": "^2.0.0", - "vite": "^5.0.0 || ^6.0.0", - "vite-node": "3.0.9", - "why-is-node-running": "^2.3.0" - }, - "bin": { - "vitest": "vitest.mjs" + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" }, "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@edge-runtime/vm": "*", - "@types/debug": "^4.1.12", - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "@vitest/browser": "3.0.9", - "@vitest/ui": "3.0.9", - "happy-dom": "*", - "jsdom": "*" - }, - "peerDependenciesMeta": { - "@edge-runtime/vm": { - "optional": true - }, - "@types/debug": { - "optional": true - }, - "@types/node": { - "optional": true - }, - "@vitest/browser": { - "optional": true - }, - "@vitest/ui": { - "optional": true - }, - "happy-dom": { - "optional": true - }, - "jsdom": { - "optional": true - } + "node": ">= 0.4" } }, - "node_modules/vue-eslint-parser": { - "version": "9.4.2", - "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz", - "integrity": "sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==", + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", "dev": true, + "license": "MIT", "dependencies": { - "debug": "^4.3.4", - "eslint-scope": "^7.1.1", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.1", - "esquery": "^1.4.0", - "lodash": "^4.17.21", - "semver": "^7.3.6" + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" }, "engines": { - "node": "^14.17.0 || >=16.0.0" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=6.0.0" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/vue-eslint-parser/node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", "dev": true, + "license": "MIT", "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">= 0.4" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/vue-eslint-parser/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">= 0.4" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/vue-eslint-parser/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "node_modules/typescript": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, "engines": { - "node": ">=4.0" + "node": ">=14.17" } }, - "node_modules/vue-eslint-parser/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", "dev": true, - "bin": { - "semver": "bin/semver.js" + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" }, "engines": { - "node": ">=10" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "makeerror": "1.0.12" + "punycode": "^2.1.0" } }, - "node_modules/watchpack": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", - "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true, - "peer": true, + "license": "MIT" + }, + "node_modules/v8-compile-cache": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz", + "integrity": "sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==", + "dev": true, + "license": "MIT" + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" } }, - "node_modules/wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "dev": true, - "dependencies": { - "defaults": "^1.0.3" - } - }, - "node_modules/webpack": { - "version": "5.91.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.91.0.tgz", - "integrity": "sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==", - "dev": true, - "peer": true, - "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.5", - "@webassemblyjs/ast": "^1.12.1", - "@webassemblyjs/wasm-edit": "^1.12.1", - "@webassemblyjs/wasm-parser": "^1.12.1", - "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", - "browserslist": "^4.21.10", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.16.0", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.11", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.2.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.10", - "watchpack": "^2.4.1", - "webpack-sources": "^3.2.3" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" + "node_modules/vue": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.22.tgz", + "integrity": "sha512-toaZjQ3a/G/mYaLSbV+QsQhIdMo9x5rrqIpYRObsJ6T/J+RyCSFwN2LHNVH9v8uIcljDNa3QzPVdv3Y6b9hAJQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.22", + "@vue/compiler-sfc": "3.5.22", + "@vue/runtime-dom": "3.5.22", + "@vue/server-renderer": "3.5.22", + "@vue/shared": "3.5.22" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "peerDependencies": { + "typescript": "*" }, "peerDependenciesMeta": { - "webpack-cli": { + "typescript": { "optional": true } } }, - "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", - "dev": true, - "peer": true, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack/node_modules/enhanced-resolve": { - "version": "5.16.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.1.tgz", - "integrity": "sha512-4U5pNsuDl0EhuZpq46M5xPslstkviJuhrdobaRDBk2Jy2KO37FDAJl4lb2KlNabxT0m4MTK2UHNrsAcphE8nyw==", + "node_modules/vue-eslint-parser": { + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.3.tgz", + "integrity": "sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" + "debug": "^4.3.4", + "eslint-scope": "^7.1.1", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.1", + "esquery": "^1.4.0", + "lodash": "^4.17.21", + "semver": "^7.3.6" }, "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack/node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" + "node": "^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=6.0.0" } }, "node_modules/which": { @@ -11143,6 +5604,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -11154,32 +5616,45 @@ } }, "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", "dev": true, + "license": "MIT", "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", "dev": true, + "license": "MIT", "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.2" + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" }, "engines": { "node": ">= 0.4" @@ -11188,22 +5663,45 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/why-is-node-running": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", - "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "siginfo": "^2.0.0", - "stackback": "0.0.2" + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" }, - "bin": { - "why-is-node-running": "cli.js" + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/word-wrap": { @@ -11211,6 +5709,7 @@ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -11219,13 +5718,15 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/write-file-atomic": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", "dev": true, + "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^3.0.7" @@ -11239,38 +5740,60 @@ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=12" } }, + "node_modules/xmlbuilder": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-13.0.2.tgz", + "integrity": "sha512-Eux0i2QdDYKbdbA6AM6xE4m6ZTZr4G4xF9kahI2ukSEMCzwce2eX9WlTI5J3s+NU7hpasFsr8hWIONae7LluAQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } - }, - "node_modules/zod": { - "version": "3.24.2", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz", - "integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==", - "dev": true, - "license": "MIT", - "peer": true, - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } } } } diff --git a/src/Resources/app/administration/package.json b/src/Resources/app/administration/package.json index 222036e48..03819e586 100644 --- a/src/Resources/app/administration/package.json +++ b/src/Resources/app/administration/package.json @@ -1,56 +1,37 @@ { - "name": "swagmigrationassistant", - "version": "1.0.0", - "description": "Migrate shop data to Shopware 6", - "main": "index.js", + "name": "swag-migration-assistant", + "description": "Plugin for migrating data to Shopware 6", "author": "shopware AG", "license": "MIT", "scripts": { "lint": "eslint --ext .js,.ts,.vue,.html,.html.twig .", - "lint-fix": "npm run lint -- --fix", + "lint:fix": "npm run lint -- --fix", "lint:scss": "stylelint ./**/*.scss", - "lint:scss-fix": "npm run lint:scss -- --fix" + "lint:scss:fix": "npm run lint:scss -- --fix", + "format": "prettier --check \"src/**/*.{js,ts}\" --config ../../../../.prettierrc.json --cache", + "format:fix": "prettier --write \"src/**/*.{js,ts}\" --config ../../../../.prettierrc.json --cache" }, "devDependencies": { - "@babel/core": "^7.24.5", - "@babel/eslint-parser": "^7.24.5", - "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/plugin-proposal-decorators": "^7.24.1", - "@babel/plugin-proposal-export-namespace-from": "^7.18.9", - "@babel/plugin-proposal-function-sent": "^7.24.1", - "@babel/plugin-proposal-json-strings": "^7.18.6", - "@babel/plugin-proposal-numeric-separator": "^7.18.6", - "@babel/plugin-proposal-throw-expressions": "^7.24.1", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-transform-runtime": "^7.24.3", - "@babel/preset-env": "^7.24.5", - "@babel/preset-typescript": "^7.24.1", - "@babel/register": "^7.23.7", - "@shopware-ag/eslint-config-base": "^2.0.0", - "@shopware-ag/stylelint-plugin-meteor": "^1.1.0", - "@typescript-eslint/eslint-plugin": "^7.9.0", - "@typescript-eslint/parser": "^7.9.0", - "babel-jest": "^29.7.0", - "babel-plugin-istanbul": "^6.1.1", - "babel-plugin-module-resolver": "^5.0.2", - "core-js": "^2.6.12", - "eslint": "^8.57.0", - "eslint-import-resolver-webpack": "^0.13.8", - "eslint-plugin-file-progress": "^1.4.0", - "eslint-plugin-filename-rules": "^1.3.1", - "eslint-plugin-html": "^8.1.1", - "eslint-plugin-inclusive-language": "^2.2.1", - "eslint-plugin-jest": "^28.5.0", - "eslint-plugin-plugin-rules": "file:../../../../../../../src/Administration/Resources/app/administration/eslint-rules/plugin-rules", - "eslint-plugin-simple-import-sort": "^12.1.0", - "eslint-plugin-sw-core-rules": "file:../../../../../../../src/Administration/Resources/app/administration/eslint-rules/core-rules", - "eslint-plugin-sw-deprecation-rules": "file:../../../../../../../src/Administration/Resources/app/administration/eslint-rules/deprecation-rules", - "eslint-plugin-sw-test-rules": "file:../../../../../../../src/Administration/Resources/app/administration/eslint-rules/test-rules", - "eslint-plugin-twig-vue": "file:../../../../../../../src/Administration/Resources/app/administration/twigVuePlugin", - "eslint-plugin-vue": "^9.26.0", - "eslint-plugin-vuejs-accessibility": "^2.3.0", - "stylelint": "^16.16.0", - "stylelint-define-config": "^16.15.0" + "@shopware-ag/eslint-config-base": "2.0.0", + "@typescript-eslint/eslint-plugin": "8.21.0", + "@typescript-eslint/parser": "8.21.0", + "eslint": "8.57.1", + "eslint-config-prettier": "9.1.0", + "eslint-plugin-file-progress": "1.5.0", + "eslint-plugin-filename-rules": "1.3.1", + "eslint-plugin-html": "7.1.0", + "eslint-plugin-import": "2.31.0", + "eslint-plugin-inclusive-language": "2.2.1", + "eslint-plugin-vue": "9.32.0", + "eslint-plugin-vuejs-accessibility": "2.4.1", + "prettier": "3.6.2", + "prettier-plugin-multiline-arrays": "3.0.6", + "stylelint": "14.16.1", + "stylelint-config-standard": "26.0.0", + "stylelint-config-standard-scss": "5.0.0", + "stylelint-junit-formatter": "0.2.2", + "typescript": "5.7.3", + "vue": "3.5.22", + "vue-eslint-parser": "9.4.3" } } diff --git a/src/Resources/app/administration/src/core/data/migration.store.js b/src/Resources/app/administration/src/core/data/migration.store.js deleted file mode 100644 index bb07eab83..000000000 --- a/src/Resources/app/administration/src/core/data/migration.store.js +++ /dev/null @@ -1,266 +0,0 @@ -const { Criteria } = Shopware.Data; - -const migrationApiService = Shopware.Service('migrationApiService'); -const repositoryFactory = Shopware.Service('repositoryFactory'); - -const migrationGeneralSettingRepository = repositoryFactory.create('swag_migration_general_setting'); - -/** - * The pinia store for handling all global data that is needed for the migration process. - * @module - * @private - * @sw-package fundamentals@after-sales - */ -export default { - namespaced: true, - - state: () => ({ - /** - * The id of the currently selected connection to a source system. - */ - connectionId: null, - - /** - * The environment information of the connection check. - */ - environmentInformation: {}, - - /** - * Date object on when the last connection check request was done. - */ - lastConnectionCheck: null, - - /** - * Flag which sets the whole module into a loading state - */ - isLoading: false, - - /** - * The possible data that the user can migrate. - */ - dataSelectionTableData: [], - - /** - * The selected data ids that the user wants to migrate. - */ - dataSelectionIds: [], - - /** - * The premapping structure, that the user must match. - */ - premapping: [], - - /** - * Flag to indicate if the user has confirmed the warning about different currencies and languages. - * Will also be set to true if there are no warnings. - */ - warningConfirmed: false, - }), - - getters: { - isPremappingValid(state) { - return !state.premapping.some((group) => { - return group.mapping.some((mapping) => { - return mapping.destinationUuid === null || mapping.destinationUuid === ''; - }); - }); - }, - - isMigrationAllowed(state) { - const tableDataIds = state.dataSelectionTableData.map((data) => { - if (data.requiredSelection === false) { - return data.id; - } - - return null; - }); - - const migrationAllowedByDataSelection = state.dataSelectionIds.some(id => tableDataIds.includes(id)); - const migrationAllowedByEnvironment = state.environmentInformation?.migrationDisabled === false; - - return migrationAllowedByDataSelection && - migrationAllowedByEnvironment && - !state.isLoading && - state.isPremappingValid && - state.warningConfirmed; - }, - }, - - actions: { - setConnectionId(id) { - this.connectionId = id; - }, - - setEnvironmentInformation(environmentInformation) { - this.environmentInformation = environmentInformation; - }, - - setLastConnectionCheck(date) { - this.lastConnectionCheck = date; - }, - - setIsLoading(isLoading) { - this.isLoading = isLoading; - }, - - setDataSelectionIds(newIds) { - this.dataSelectionIds = newIds; - }, - - setDataSelectionTableData(newTableData) { - this.dataSelectionTableData = newTableData; - }, - - // merges the existing premapping (in the state) with the newly provided one. - // resets the state premapping if an empty array is passed as an argument. - setPremapping(newPremapping) { - if (newPremapping === undefined || newPremapping === null || newPremapping.length < 1) { - this.premapping = []; - return; - } - - newPremapping.forEach((group) => { - // the premapping is grouped by entity, find the corresponding group in the state - let existingGroup = this.premapping.find( - (existingGroupItem) => existingGroupItem.entity === group.entity, - ); - - if (!existingGroup) { - // if it doesn't exist, create a new group for this entity with no mappings - existingGroup = { - choices: group.choices, - entity: group.entity, - mapping: [], - }; - // and add it to the state premapping groups - this.premapping.push(existingGroup); - } else { - // in case the group already exists, override the choices by the latest ones received from the server - existingGroup.choices = group.choices; - } - - group.mapping.forEach((mapping) => { - const existingMapping = existingGroup.mapping.find( - // sourceId is unique per entity and always provided by the backend - (existingMappingItem) => existingMappingItem.sourceId === mapping.sourceId, - ); - - if (existingMapping) { - // mapping already exist, check if it was already set and override if not - if (!existingMapping.destinationUuid) { - existingMapping.destinationUuid = mapping.destinationUuid; - } - return; - } - - const newMapping = { - ...mapping, - // build a unique identifier, which can be used as a vue key for reactivity (v-for) - id: `${existingGroup.entity}-${mapping.sourceId}`, - }; - - // either push the new mapping to the start or end - // depending on if it is already filled (automatically by the backend) - if (mapping.destinationUuid) { - existingGroup.mapping.push(newMapping); - } else { - existingGroup.mapping.unshift(newMapping); - } - }); - }); - }, - - setWarningConfirmed(confirmed) { - this.warningConfirmed = confirmed; - }, - - async init(forceFullStateReload = false) { - this.isLoading = true; - - const connectionIdChanged = await this.fetchConnectionId(); - await this.fetchEnvironmentInformation(); // Always fetch latest environment info - - if (forceFullStateReload || connectionIdChanged) { - // First, clear old user input - this.premapping = []; - this.dataSelectionIds = []; - this.warningConfirmed = false; - - // Then fetch new data - await this.fetchDataSelectionIds(); - } - - this.isLoading = false; - }, - - /** - * @returns {Promise} whether the connection id has changed to a new valid one - */ - async fetchConnectionId() { - try { - const criteria = new Criteria(1, 1); - const settings = await migrationGeneralSettingRepository.search(criteria, Shopware.Context.api); - - if (settings.length === 0) { - return false; - } - - const newConnectionId = settings.first().selectedConnectionId; - if (newConnectionId === this.connectionId) { - return false; - } - - this.connectionId = newConnectionId; - return true; - } catch (e) { - await this.createErrorNotification('swag-migration.api-error.fetchConnectionId'); - this.connectionId = null; - return false; - } - }, - - async fetchEnvironmentInformation() { - this.environmentInformation = {}; - - if (this.connectionId === null) { - return; - } - - try { - this.environmentInformation = await migrationApiService.checkConnection(this.connectionId); - this.lastConnectionCheck = new Date(); - } catch (e) { - await this.createErrorNotification('swag-migration.api-error.checkConnection'); - } - }, - - async fetchDataSelectionIds() { - this.dataSelectionTableData = []; - - if (this.connectionId === null) { - return; - } - - try { - const dataSelection = await migrationApiService.getDataSelection(this.connectionId); - this.dataSelectionTableData = dataSelection; - this.dataSelectionIds = dataSelection.filter(selection => selection.requiredSelection) - .map(selection => selection.id); - } catch (e) { - await this.createErrorNotification('swag-migration.api-error.getDataSelection'); - } - }, - - async createErrorNotification(errorMessageKey) { - await this.$patch(() => { - // Assuming notification system exists - // Replace this with how notifications are handled in your system - Shopware.State.dispatch('notification/createNotification', { - variant: 'error', - title: Shopware.Snippet.tc('global.default.error'), - message: Shopware.Snippet.tc(errorMessageKey), - }); - }); - }, - }, -}; diff --git a/src/Resources/app/administration/src/core/service/api/swag-migration.api.service.js b/src/Resources/app/administration/src/core/service/api/swag-migration.api.service.js deleted file mode 100644 index 2bb568385..000000000 --- a/src/Resources/app/administration/src/core/service/api/swag-migration.api.service.js +++ /dev/null @@ -1,245 +0,0 @@ -const ApiService = Shopware.Classes.ApiService; - -/** - * @private - * @sw-package fundamentals@after-sales - */ -export const MIGRATION_STEP = Object.freeze({ - IDLE: 'idle', - FETCHING: 'fetching', - WRITING: 'writing', - MEDIA_PROCESSING: 'media-processing', - CLEANUP: 'cleanup', - INDEXING: 'indexing', - WAITING_FOR_APPROVE: 'waiting-for-approve', - ABORTING: 'aborting', -}); - -/** - * @private - * @sw-package fundamentals@after-sales - */ -class MigrationApiService extends ApiService { - constructor(httpClient, loginService, apiEndpoint = 'migration') { - super(httpClient, loginService, apiEndpoint); - this.basicConfig = { - timeout: 30000, - version: Shopware.Context.api.apiVersion, - }; - } - - updateConnectionCredentials(connectionId, credentialFields, additionalHeaders = {}) { - const headers = this.getBasicHeaders(additionalHeaders); - - return this.httpClient.post(`_action/${this.getApiBasePath()}/update-connection-credentials`, { - connectionId, - credentialFields, - }, { - ...this.basicConfig, - headers, - }).then((response) => { - return ApiService.handleResponse(response); - }); - } - - checkConnection(connectionId, additionalHeaders = {}) { - const headers = this.getBasicHeaders(additionalHeaders); - - return this.httpClient.post(`_action/${this.getApiBasePath()}/check-connection`, { connectionId }, { - ...this.basicConfig, - headers, - }).then((response) => { - return ApiService.handleResponse(response); - }); - } - - getDataSelection(connectionId, additionalHeaders = {}) { - const headers = this.getBasicHeaders(additionalHeaders); - - return this.httpClient.get(`_action/${this.getApiBasePath()}/data-selection`, { - ...this.basicConfig, - params: { - connectionId, - }, - headers, - }).then((response) => { - return ApiService.handleResponse(response); - }); - } - - /** - * @param {string[]} dataSelectionIds - */ - generatePremapping(dataSelectionIds) { - const headers = this.getBasicHeaders(); - - return this.httpClient.post(`_action/${this.getApiBasePath()}/generate-premapping`, { dataSelectionIds }, { - ...this.basicConfig, - headers, - }).then((response) => { - return ApiService.handleResponse(response); - }); - } - - writePremapping(premapping) { - const headers = this.getBasicHeaders(); - - return this.httpClient.post(`_action/${this.getApiBasePath()}/write-premapping`, { premapping }, { - ...this.basicConfig, - headers, - }).then((response) => { - return ApiService.handleResponse(response); - }); - } - - /** - * @param {string[]} dataSelectionNames - */ - startMigration(dataSelectionNames) { - const headers = this.getBasicHeaders(); - - return this.httpClient.post(`_action/${this.getApiBasePath()}/start-migration`, { - dataSelectionNames, - }, { - ...this.basicConfig, - headers, - }).then((response) => { - return ApiService.handleResponse(response); - }); - } - - getState() { - const headers = this.getBasicHeaders(); - - return this.httpClient.get(`_action/${this.getApiBasePath()}/get-state`, { - ...this.basicConfig, - headers, - }).then((response) => { - return ApiService.handleResponse(response); - }); - } - - approveFinishedMigration() { - const headers = this.getBasicHeaders(); - - return this.httpClient.post(`_action/${this.getApiBasePath()}/approve-finished`, {}, { - ...this.basicConfig, - headers, - }).then((response) => { - return ApiService.handleResponse(response); - }); - } - - abortMigration() { - const headers = this.getBasicHeaders(); - - return this.httpClient.post(`_action/${this.getApiBasePath()}/abort-migration`, {}, { - ...this.basicConfig, - headers, - }).then((response) => { - return ApiService.handleResponse(response); - }); - } - - getProfiles() { - const headers = this.getBasicHeaders(); - - return this.httpClient.get(`_action/${this.getApiBasePath()}/get-profiles`, { - ...this.basicConfig, - headers, - }).then((response) => { - return ApiService.handleResponse(response); - }); - } - - getGateways(profileName) { - const headers = this.getBasicHeaders(); - - return this.httpClient.get(`_action/${this.getApiBasePath()}/get-gateways`, { - ...this.basicConfig, - params: { - profileName, - }, - headers, - }).then((response) => { - return ApiService.handleResponse(response); - }); - } - - getProfileInformation(profileName, gatewayName) { - const headers = this.getBasicHeaders(); - - return this.httpClient.get(`_action/${this.getApiBasePath()}/get-profile-information`, { - ...this.basicConfig, - params: { - profileName, - gatewayName, - }, - headers, - }).then((response) => { - return ApiService.handleResponse(response); - }); - } - - getGroupedLogsOfRun(runUuid) { - const headers = this.getBasicHeaders(); - - return this.httpClient.get(`${this.getApiBasePath()}/get-grouped-logs-of-run`, { - ...this.basicConfig, - params: { - runUuid, - }, - headers, - }).then((response) => { - return ApiService.handleResponse(response); - }); - } - - clearDataOfRun(runUuid) { - const headers = this.getBasicHeaders(); - - return this.httpClient.post(`_action/${this.getApiBasePath()}/clear-data-of-run`, { - runUuid, - }, { - ...this.basicConfig, - headers, - }).then((response) => { - return ApiService.handleResponse(response); - }); - } - - resetChecksums(connectionId, additionalHeaders = {}) { - const headers = this.getBasicHeaders(additionalHeaders); - - return this.httpClient.post(`_action/${this.getApiBasePath()}/reset-checksums`, { - connectionId, - }, { - ...this.basicConfig, - headers, - }).then((response) => { - return ApiService.handleResponse(response); - }); - } - - cleanupMigrationData(additionalHeaders = {}) { - const headers = this.getBasicHeaders(additionalHeaders); - return this.httpClient.post(`_action/${this.getApiBasePath()}/cleanup-migration-data`, { - ...this.basicConfig, - headers, - }); - } - - isMediaProcessing(additionalHeaders = {}) { - const headers = this.getBasicHeaders(additionalHeaders); - return this.httpClient.get(`_action/${this.getApiBasePath()}/is-media-processing`, { - ...this.basicConfig, - headers, - }); - } -} - -/** - * @private - * @sw-package fundamentals@after-sales - */ -export default MigrationApiService; diff --git a/src/Resources/app/administration/src/core/service/api/swag-migration.api.service.ts b/src/Resources/app/administration/src/core/service/api/swag-migration.api.service.ts new file mode 100644 index 000000000..9c878aac6 --- /dev/null +++ b/src/Resources/app/administration/src/core/service/api/swag-migration.api.service.ts @@ -0,0 +1,598 @@ +import type { AxiosInstance, AxiosResponse, AxiosRequestConfig } from 'axios'; +import type { LoginService } from '@administration/src/core/service/login.service'; +import type { ApiResponse } from '@administration/src/core/service/api.service'; +import type { + MigrationDataSelection, + MigrationEnvironmentInformation, + MigrationGateway, + MigrationProfile, + MigrationState, + MigrationPremapping, + MigrationCredentials, + MigrationError, +} from '../../../type/types'; + +type AdditionalHeaders = Record; + +const ApiService = Shopware.Classes.ApiService; + +/** + * @private + */ +export const MIGRATION_API_SERVICE = 'migrationApiService'; + +/** + * @private + * @sw-package fundamentals@after-sales + */ +export const MIGRATION_STEP = { + IDLE: 'idle', + FETCHING: 'fetching', + ERROR_RESOLUTION: 'error-resolution', + WRITING: 'writing', + MEDIA_PROCESSING: 'media-processing', + CLEANUP: 'cleanup', + INDEXING: 'indexing', + WAITING_FOR_APPROVE: 'waiting-for-approve', + ABORTING: 'aborting', +} as const; + +/** + * @private + */ +export type LogGroup = { + code: string; + entityName: string | null; + fieldName: string | null; + count: number; +}; + +/** + * @private + */ +export type LogLevelCounts = { + error: number; + warning: number; + info: number; +}; + +/** + * @private + * @sw-package fundamentals@after-sales + */ +export default class MigrationApiService extends ApiService { + private readonly basicConfig: AxiosRequestConfig & { version: string }; + + constructor(httpClient: AxiosInstance, loginService: LoginService, apiEndpoint = 'migration') { + super(httpClient, loginService, apiEndpoint); + // @ts-ignore + this.name = MIGRATION_API_SERVICE; + this.basicConfig = { + timeout: 30000, + version: Shopware.Context.api.apiVersion, + }; + } + + async updateConnectionCredentials( + connectionId: string, + credentialFields: Record, + additionalHeaders: AdditionalHeaders = {}, + ): Promise> { + // @ts-ignore + const headers = this.getBasicHeaders(additionalHeaders); + + // @ts-ignore + return this.httpClient + .post( + // @ts-ignore + `_action/${this.getApiBasePath()}/update-connection-credentials`, + { + connectionId, + credentialFields, + }, + { + ...this.basicConfig, + headers, + }, + ) + .then((response: AxiosResponse) => { + return ApiService.handleResponse(response as AxiosResponse); + }); + } + + async checkConnection( + connectionId: string, + additionalHeaders: AdditionalHeaders = {}, + ): Promise { + // @ts-ignore + const headers = this.getBasicHeaders(additionalHeaders); + + // @ts-ignore + return this.httpClient + .post( + // @ts-ignore + `_action/${this.getApiBasePath()}/check-connection`, + { connectionId }, + { + ...this.basicConfig, + headers, + }, + ) + .then((response: AxiosResponse) => { + return ApiService.handleResponse(response); + }); + } + + async getDataSelection( + connectionId: string, + additionalHeaders: AdditionalHeaders = {}, + ): Promise { + // @ts-ignore + const headers = this.getBasicHeaders(additionalHeaders); + + return ( + // @ts-ignore + this.httpClient + // @ts-ignore + .get(`_action/${this.getApiBasePath()}/data-selection`, { + ...this.basicConfig, + params: { + connectionId, + }, + headers, + }) + .then((response: AxiosResponse) => { + return ApiService.handleResponse(response); + }) + ); + } + + async generatePremapping(dataSelectionIds: string[]): Promise { + // @ts-ignore + const headers = this.getBasicHeaders(); + + // @ts-ignore + return this.httpClient + .post( + // @ts-ignore + `_action/${this.getApiBasePath()}/generate-premapping`, + { dataSelectionIds }, + { + ...this.basicConfig, + headers, + }, + ) + .then((response: AxiosResponse) => { + return ApiService.handleResponse(response); + }); + } + + async writePremapping(premapping: MigrationPremapping[]): Promise> { + // @ts-ignore + const headers = this.getBasicHeaders(); + + // @ts-ignore + return this.httpClient + .post( + // @ts-ignore + `_action/${this.getApiBasePath()}/write-premapping`, + { premapping }, + { + ...this.basicConfig, + headers, + }, + ) + .then((response: AxiosResponse) => { + return ApiService.handleResponse(response); + }); + } + + async startMigration(dataSelectionNames: string[]): Promise> { + // @ts-ignore + const headers = this.getBasicHeaders(); + + // @ts-ignore + return this.httpClient + .post( + // @ts-ignore + `_action/${this.getApiBasePath()}/start-migration`, + { + dataSelectionNames, + }, + { + ...this.basicConfig, + headers, + }, + ) + .then((response: AxiosResponse) => { + return ApiService.handleResponse(response); + }); + } + + async getState(): Promise { + // @ts-ignore + const headers = this.getBasicHeaders(); + + return ( + // @ts-ignore + this.httpClient + // @ts-ignore + .get(`_action/${this.getApiBasePath()}/get-state`, { + ...this.basicConfig, + headers, + }) + .then((response: AxiosResponse) => { + return ApiService.handleResponse(response); + }) + ); + } + + async approveFinishedMigration(): Promise> { + // @ts-ignore + const headers = this.getBasicHeaders(); + + // @ts-ignore + return this.httpClient + .post( + // @ts-ignore + `_action/${this.getApiBasePath()}/approve-finished`, + {}, + { + ...this.basicConfig, + headers, + }, + ) + .then((response: AxiosResponse) => { + return ApiService.handleResponse(response); + }); + } + + async abortMigration(): Promise> { + // @ts-ignore + const headers = this.getBasicHeaders(); + + // @ts-ignore + return this.httpClient + .post( + // @ts-ignore + `_action/${this.getApiBasePath()}/abort-migration`, + {}, + { + ...this.basicConfig, + headers, + }, + ) + .then((response: AxiosResponse) => { + return ApiService.handleResponse(response); + }); + } + + async continueAfterErrorResolution(): Promise> { + // @ts-ignore + const headers = this.getBasicHeaders(); + + // @ts-ignore + return this.httpClient + .post( + // @ts-ignore + `_action/${this.getApiBasePath()}/resume-after-fixes`, + {}, + { + ...this.basicConfig, + headers, + }, + ) + .then((response: AxiosResponse) => { + return ApiService.handleResponse(response); + }); + } + + async getProfiles(): Promise { + // @ts-ignore + const headers = this.getBasicHeaders(); + + return ( + // @ts-ignore + this.httpClient + // @ts-ignore + .get(`_action/${this.getApiBasePath()}/get-profiles`, { + ...this.basicConfig, + headers, + }) + .then((response: AxiosResponse) => { + return ApiService.handleResponse(response); + }) + ); + } + + async getGateways(profileName: string): Promise { + // @ts-ignore + const headers = this.getBasicHeaders(); + + return ( + // @ts-ignore + this.httpClient + // @ts-ignore + .get(`_action/${this.getApiBasePath()}/get-gateways`, { + ...this.basicConfig, + params: { + profileName, + }, + headers, + }) + .then((response: AxiosResponse) => { + return ApiService.handleResponse(response); + }) + ); + } + + async getProfileInformation(profileName: string, gatewayName: string): Promise { + // @ts-ignore + const headers = this.getBasicHeaders(); + + return ( + // @ts-ignore + this.httpClient + // @ts-ignore + .get(`_action/${this.getApiBasePath()}/get-profile-information`, { + ...this.basicConfig, + params: { + profileName, + gatewayName, + }, + headers, + }) + .then((response: AxiosResponse) => { + return ApiService.handleResponse(response); + }) + ); + } + + async getGroupedLogsOfRun(runUuid: string): Promise<{ + total: number; + downloadUrl: string; + items: MigrationError[]; + }> { + // @ts-ignore + const headers = this.getBasicHeaders(); + + return ( + // @ts-ignore + this.httpClient + // @ts-ignore + .get(`_action/${this.getApiBasePath()}/get-grouped-logs-of-run`, { + ...this.basicConfig, + params: { + runUuid, + }, + headers, + }) + .then((response: AxiosResponse) => { + return ApiService.handleResponse(response); + }) + ); + } + + async clearDataOfRun(runUuid: string): Promise> { + // @ts-ignore + const headers = this.getBasicHeaders(); + + // @ts-ignore + return this.httpClient + .post( + // @ts-ignore + `_action/${this.getApiBasePath()}/clear-data-of-run`, + { + runUuid, + }, + { + ...this.basicConfig, + headers, + }, + ) + .then((response: AxiosResponse) => { + return ApiService.handleResponse(response); + }); + } + + async resetChecksums(connectionId: string, additionalHeaders: AdditionalHeaders = {}): Promise> { + // @ts-ignore + const headers = this.getBasicHeaders(additionalHeaders); + + // @ts-ignore + return this.httpClient + .post( + // @ts-ignore + `_action/${this.getApiBasePath()}/reset-checksums`, + { + connectionId, + }, + { + ...this.basicConfig, + headers, + }, + ) + .then((response: AxiosResponse) => { + return ApiService.handleResponse(response); + }); + } + + async cleanupMigrationData(additionalHeaders: AdditionalHeaders = {}): Promise> { + // @ts-ignore + const headers = this.getBasicHeaders(additionalHeaders); + + // @ts-ignore + return this.httpClient.post( + // @ts-ignore + `_action/${this.getApiBasePath()}/cleanup-migration-data`, + {}, + { + ...this.basicConfig, + headers, + }, + ); + } + + async isMediaProcessing(additionalHeaders: AdditionalHeaders = {}): Promise { + // @ts-ignore + const headers = this.getBasicHeaders(additionalHeaders); + + // @ts-ignore + return this.httpClient.get(`_action/${this.getApiBasePath()}/is-media-processing`, { + ...this.basicConfig, + headers, + }); + } + + async downloadLogsOfRun(runUuid: string, additionalHeaders: AdditionalHeaders = {}): Promise { + // @ts-ignore + const headers = this.getBasicHeaders(additionalHeaders); + + // @ts-ignore + return this.httpClient + .post( + // @ts-ignore + `_action/${this.getApiBasePath()}/download-logs-of-run`, + { runUuid }, + { + ...this.basicConfig, + headers, + responseType: 'blob', + }, + ) + .then((response: AxiosResponse) => { + return response.data; + }); + } + + async getLogGroups( + runId: string, + level: string, + page: number, + limit: number, + sortBy: string, + sortDirection: 'ASC' | 'DESC', + filter: { + code: string | null; + status: 'resolved' | 'unresolved' | null; + entity: string | null; + field: string | null; + }, + additionalHeaders: AdditionalHeaders = {}, + ): Promise<{ + total: number; + items: LogGroup[]; + levelCounts: LogLevelCounts; + }> { + // @ts-ignore + const headers = this.getBasicHeaders(additionalHeaders); + + const params: Record = { + runId, + level, + page, + limit, + sortBy, + sortDirection, + }; + + if (filter.code) { + params.filterCode = filter.code; + } + + if (filter.status) { + params.filterStatus = filter.status; + } + + if (filter.entity) { + params.filterEntity = filter.entity; + } + + if (filter.field) { + params.filterField = filter.field; + } + + return ( + // @ts-ignore + this.httpClient + // @ts-ignore + .get(`_action/${this.getApiBasePath()}/get-log-groups`, { + ...this.basicConfig, + params, + headers, + }) + .then((response: AxiosResponse) => { + return ApiService.handleResponse(response); + }) + ); + } + + async isResettingChecksums(): Promise { + // @ts-ignore + const headers = this.getBasicHeaders(); + + return ( + // @ts-ignore + this.httpClient + // @ts-ignore + .get(`_action/${this.getApiBasePath()}/is-resetting-checksums`, { + ...this.basicConfig, + headers, + }) + .then((response: AxiosResponse) => { + return ApiService.handleResponse(response); + }) + ); + } + + async isTruncatingMigrationData(): Promise { + // @ts-ignore + const headers = this.getBasicHeaders(); + + return ( + // @ts-ignore + this.httpClient + // @ts-ignore + .get(`_action/${this.getApiBasePath()}/is-truncating-migration-data`, { + ...this.basicConfig, + headers, + }) + .then((response: AxiosResponse) => { + return ApiService.handleResponse(response); + }) + ); + } + + async getAllLogIds( + runId: string, + code: string, + entityName: string, + fieldName: string, + connectionId?: string, + additionalHeaders: AdditionalHeaders = {}, + ): Promise<{ ids: string[] }> { + // @ts-ignore + const headers = this.getBasicHeaders(additionalHeaders); + + // @ts-ignore + return this.httpClient + .post( + // @ts-ignore + `_action/${this.getApiBasePath()}/get-all-log-ids`, + { + runId, + code, + entityName, + fieldName, + connectionId, + }, + { + ...this.basicConfig, + headers, + }, + ) + .then((response: AxiosResponse) => { + return ApiService.handleResponse(response); + }); + } +} diff --git a/src/Resources/app/administration/src/core/service/index.js b/src/Resources/app/administration/src/core/service/index.ts similarity index 57% rename from src/Resources/app/administration/src/core/service/index.js rename to src/Resources/app/administration/src/core/service/index.ts index 58b0732ac..c6a67dc77 100644 --- a/src/Resources/app/administration/src/core/service/index.js +++ b/src/Resources/app/administration/src/core/service/index.ts @@ -1,4 +1,4 @@ -import MigrationApiService from './api/swag-migration.api.service'; +import MigrationApiService, { MIGRATION_API_SERVICE } from './api/swag-migration.api.service'; const { Application } = Shopware; @@ -6,8 +6,7 @@ const { Application } = Shopware; * @sw-package fundamentals@after-sales * @private */ - -Application.addServiceProvider('migrationApiService', (container) => { +Application.addServiceProvider(MIGRATION_API_SERVICE, (container: ServiceContainer) => { const initContainer = Application.getContainer('init'); return new MigrationApiService(initContainer.httpClient, container.loginService); }); diff --git a/src/Resources/app/administration/src/main.ts b/src/Resources/app/administration/src/main.ts index 1494c0a7d..0a509ed85 100644 --- a/src/Resources/app/administration/src/main.ts +++ b/src/Resources/app/administration/src/main.ts @@ -2,8 +2,7 @@ * @sw-package fundamentals@after-sales * @private */ - +import './type/global.types'; +import './init/translation.init'; import './core/service'; import './module/swag-migration'; - -import './init/translation.init'; diff --git a/src/Resources/app/administration/src/module/swag-migration/acl/index.ts b/src/Resources/app/administration/src/module/swag-migration/acl/index.ts new file mode 100644 index 000000000..971f38cd6 --- /dev/null +++ b/src/Resources/app/administration/src/module/swag-migration/acl/index.ts @@ -0,0 +1,81 @@ +const MIGRATION_ACL_KEY = 'swag_migration'; + +const acl = { + category: 'permissions', + parent: 'settings', + key: MIGRATION_ACL_KEY, + roles: { + viewer: { + privileges: [ + 'swag_migration_connection:read', + 'swag_migration_data:read', + 'swag_migration_fix:read', + 'swag_migration_general_setting:read', + 'swag_migration_logging:read', + 'swag_migration_mapping:read', + 'swag_migration_media_file:read', + 'swag_migration_run:read', + 'swag_migration_history:read', + 'system_config:read', + ], + dependencies: [], + }, + editor: { + privileges: [ + 'swag_migration_connection:update', + 'swag_migration_data:update', + 'swag_migration_fix:update', + 'swag_migration_general_setting:update', + 'swag_migration_logging:update', + 'swag_migration_mapping:update', + 'swag_migration_media_file:update', + 'swag_migration_run:update', + 'swag_migration_history:update', + ], + dependencies: [ + 'swag_migration.viewer', + ], + }, + creator: { + privileges: [ + 'swag_migration_connection:create', + 'swag_migration_data:create', + 'swag_migration_fix:create', + 'swag_migration_general_setting:create', + 'swag_migration_logging:create', + 'swag_migration_mapping:create', + 'swag_migration_media_file:create', + 'swag_migration_run:create', + 'swag_migration_history:create', + ], + dependencies: [ + 'swag_migration.viewer', + 'swag_migration.editor', + ], + }, + deleter: { + privileges: [ + 'swag_migration_connection:delete', + 'swag_migration_data:delete', + 'swag_migration_fix:delete', + 'swag_migration_general_setting:delete', + 'swag_migration_logging:delete', + 'swag_migration_mapping:delete', + 'swag_migration_media_file:delete', + 'swag_migration_run:delete', + 'swag_migration_history:delete', + ], + dependencies: [ + 'swag_migration.viewer', + ], + }, + }, +}; + +Shopware.Service('privileges').addPrivilegeMappingEntry(acl); + +/** + * @private + * @sw-package fundamentals@after-sales + */ +export { MIGRATION_ACL_KEY, acl }; diff --git a/src/Resources/app/administration/src/module/swag-migration/component/card/index.js b/src/Resources/app/administration/src/module/swag-migration/component/card/index.js deleted file mode 100644 index 21dbe0f7a..000000000 --- a/src/Resources/app/administration/src/module/swag-migration/component/card/index.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * @sw-package fundamentals@after-sales - * @private - */ - -import './swag-migration-shop-information'; -import './swag-migration-premapping'; -import './swag-migration-progress-bar'; -import './swag-migration-assistant'; -import './swag-migration-confirm-warning'; diff --git a/src/Resources/app/administration/src/module/swag-migration/component/card/index.ts b/src/Resources/app/administration/src/module/swag-migration/component/card/index.ts new file mode 100644 index 000000000..a5b3dbc90 --- /dev/null +++ b/src/Resources/app/administration/src/module/swag-migration/component/card/index.ts @@ -0,0 +1,8 @@ +/** + * @sw-package fundamentals@after-sales + * @private + */ +Shopware.Component.register('swag-migration-shop-information', () => import('./swag-migration-shop-information')); +Shopware.Component.register('swag-migration-premapping', () => import('./swag-migration-premapping')); +Shopware.Component.register('swag-migration-progress-bar', () => import('./swag-migration-progress-bar')); +Shopware.Component.register('swag-migration-confirm-warning', () => import('./swag-migration-confirm-warning')); diff --git a/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-assistant/index.js b/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-assistant/index.js deleted file mode 100644 index f13ba7c50..000000000 --- a/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-assistant/index.js +++ /dev/null @@ -1,18 +0,0 @@ -import template from './swag-migration-assistant.html.twig'; -import './swag-migration-assistant.scss'; - -const { Component } = Shopware; - -/** - * @private - * @sw-package fundamentals@after-sales - */ -Component.register('swag-migration-assistant', { - computed: { - assetFilter() { - return Shopware.Filter.getByName('asset'); - }, - }, - - template, -}); diff --git a/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-assistant/swag-migration-assistant.html.twig b/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-assistant/swag-migration-assistant.html.twig deleted file mode 100644 index 4e627c403..000000000 --- a/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-assistant/swag-migration-assistant.html.twig +++ /dev/null @@ -1,102 +0,0 @@ -{% block swag_migration_assistant %} - - - {% block swag_migration_assistant_headline %} -

- {{ $tc('swag-migration.index.assistantCard.headline') }} -

- {% endblock %} - - {% block swag_migration_assistant_connection %} -
- - {% block swag_migration_assistant_connection_illustration %} - - {% endblock %} - - {% block swag_migration_assistant_connection_title %} -
- {{ $tc('swag-migration.index.assistantCard.connection.title') }} -
- {% endblock %} - - {% block swag_migration_assistant_connection_content %} -

- {{ $tc('swag-migration.index.assistantCard.connection.content') }} -

- {% endblock %} - - {% block swag_migration_assistant_connection_content_link %} - - {% endblock %} -
- {% endblock %} - - {% block swag_migration_assistant_dataSelection %} -
- - {% block swag_migration_assistant_dataSelection_illustration %} - - {% endblock %} - - {% block swag_migration_assistant_dataSelection_title %} -
- {{ $tc('swag-migration.index.assistantCard.dataSelection.title') }} -
- {% endblock %} - - {% block swag_migration_assistant_dataSelection_content %} -

- {{ $tc('swag-migration.index.assistantCard.dataSelection.content') }} -

- {% endblock %} -
- {% endblock %} - - {% block swag_migration_assistant_migrationOverview %} -
- - {% block swag_migration_assistant_migrationOverview_illustration %} - - {% endblock %} - - {% block swag_migration_assistant_migrationOverview_title %} -
- {{ $tc('swag-migration.index.assistantCard.migrationOverview.title') }} -
- {% endblock %} - - {% block swag_migration_assistant_migrationOverview_content %} -

- {{ $tc('swag-migration.index.assistantCard.migrationOverview.content') }} -

- {% endblock %} -
- {% endblock %} - - {% block swag_migration_assistant_finish %} -
- - {% block swag_migration_assistant_finish_title %} -
- {{ $tc('swag-migration.index.assistantCard.finish') }} -
- {% endblock %} -
- {% endblock %} -
-{% endblock %} diff --git a/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-assistant/swag-migration-assistant.scss b/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-assistant/swag-migration-assistant.scss deleted file mode 100644 index 916e760c0..000000000 --- a/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-assistant/swag-migration-assistant.scss +++ /dev/null @@ -1,46 +0,0 @@ -@import "~scss/variables"; - -.swag-migration-assistant { - h4.swag-migration-assistant__headline { - font-size: 32px; - text-align: center; - margin: 0; - padding-top: var(--scale-size-10); - } - - .swag-migration-assistant__paragraph { - text-align: center; - width: 80%; - margin: var(--scale-size-80) auto 0 auto; - - &:first-of-type { - margin-top: var(--scale-size-64); - } - - &:last-of-type { - margin-top: var(--scale-size-40); - } - } - - .swag-migration-assistant__illustration { - width: 136px; - display: block; - margin: 0 auto; - padding-bottom: var(--scale-size-16); - } - - h5.swag-migration-assistant__title { - font-weight: 600; - margin-bottom: var(--scale-size-8); - } - - .swag-migration-assistant__content { - white-space: pre-line; - } - - .swag-migration-assistant__content, - .swag-migration-assistant__link a.link { - font-size: $font-size-xxs; - line-height: 22px; - } -} diff --git a/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-confirm-warning/index.js b/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-confirm-warning/index.js deleted file mode 100644 index e42ab3ece..000000000 --- a/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-confirm-warning/index.js +++ /dev/null @@ -1,69 +0,0 @@ -import template from './swag-migration-confirm-warning.html.twig'; -import './swag-migration-confirm-warning.scss'; - -const { Component, Store } = Shopware; -const { mapState } = Shopware.Component.getComponentHelper(); - -/** - * @private - * @sw-package fundamentals@after-sales - */ -Component.register('swag-migration-confirm-warning', { - template, - - data() { - return { - isCurrencyChecked: false, - isLanguageChecked: false, - }; - }, - - computed: { - ...mapState(() => Store.get('swagMigration'), [ - 'environmentInformation', - ]), - - hasDifferentCurrency() { - return this.sourceSystemCurrency !== this.targetSystemCurrency; - }, - - sourceSystemCurrency() { - return this.environmentInformation.sourceSystemCurrency; - }, - - targetSystemCurrency() { - return this.environmentInformation.targetSystemCurrency; - }, - - hasDifferentLanguage() { - return this.sourceSystemLanguage !== this.targetSystemLanguage; - }, - - sourceSystemLanguage() { - return this.environmentInformation.sourceSystemLocale; - }, - - targetSystemLanguage() { - return this.environmentInformation.targetSystemLocale; - }, - - isContinuable() { - return (!this.hasDifferentCurrency || this.isCurrencyChecked) && - (!this.hasDifferentLanguage || this.isLanguageChecked); - }, - }, - - created() { - this.createdComponent(); - }, - - methods: { - createdComponent() { - this.onCheckboxValueChanged(); - }, - - onCheckboxValueChanged() { - Store.get('swagMigration').setWarningConfirmed(this.isContinuable); - }, - }, -}); diff --git a/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-confirm-warning/index.ts b/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-confirm-warning/index.ts new file mode 100644 index 000000000..0a2e6553f --- /dev/null +++ b/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-confirm-warning/index.ts @@ -0,0 +1,40 @@ +import template from './swag-migration-confirm-warning.html.twig'; +import './swag-migration-confirm-warning.scss'; +import { MIGRATION_STORE_ID } from '../../../store/migration.store'; + +const { mapState } = Shopware.Component.getComponentHelper(); + +/** + * @private + * @sw-package fundamentals@after-sales + */ +export default Shopware.Component.wrapComponentConfig({ + template, + + computed: { + sourceSystemCurrency() { + return this.environmentInformation.sourceSystemCurrency; + }, + + targetSystemCurrency() { + return this.environmentInformation.targetSystemCurrency; + }, + + sourceSystemLanguage() { + return this.environmentInformation.sourceSystemLocale; + }, + + targetSystemLanguage() { + return this.environmentInformation.targetSystemLocale; + }, + + ...mapState( + () => Shopware.Store.get(MIGRATION_STORE_ID), + [ + 'environmentInformation', + 'hasCurrencyMismatch', + 'hasLanguageMismatch', + ], + ), + }, +}); diff --git a/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-confirm-warning/swag-migration-confirm-warning.html.twig b/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-confirm-warning/swag-migration-confirm-warning.html.twig index 1c378f3eb..248b60920 100644 --- a/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-confirm-warning/swag-migration-confirm-warning.html.twig +++ b/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-confirm-warning/swag-migration-confirm-warning.html.twig @@ -1,108 +1,21 @@ {% block swag_migration_confirm_warning %}
- - {% block swag_migration_confirm_warning_card %} - - - {% block swag_migration_confirm_warning_bubble %} -
- -
- {% endblock %} - - {% block swag_migration_confirm_warning_title %} -
- {{ $tc('swag-migration.index.confirmWarningCard.currencyMismatch.title') }} -
- {% endblock %} - - {% block swag_migration_confirm_warning_text %} -

- {{ $tc('swag-migration.index.confirmWarningCard.currencyMismatch.text', { sourceSystemCurrency, targetSystemCurrency }, 0) }} -

- {% endblock %} - - {% block swag_migration_confirm_warning_alert %} - - {{ $tc('swag-migration.index.confirmWarningCard.currencyMismatch.info') }} - - {% endblock %} - - {% block swag_migration_confirm_warning_question %} -

- {{ $tc('swag-migration.index.confirmWarningCard.currencyMismatch.question', { targetSystemCurrency }, 0) }} -

- {% endblock %} - - {% block swag_migration_confirm_warning_checkbox %} - - {% endblock %} -
- {% endblock %} - - {% block swag_migration_confirm_language_warning_card %} - - - {% block swag_migration_confirm_language_warning_bubble %} -
- -
- {% endblock %} - - {% block swag_migration_confirm_language_warning_title %} -
- {{ $tc('swag-migration.index.confirmWarningCard.languageMismatch.title') }} -
- {% endblock %} - - {% block swag_migration_confirm_language_warning_text %} -

- {{ $tc('swag-migration.index.confirmWarningCard.languageMismatch.text', { sourceSystemLanguage, targetSystemLanguage }, 0) }} -

- {% endblock %} - - {% block swag_migration_confirm_language_warning_alert %} - - {{ $tc('swag-migration.index.confirmWarningCard.languageMismatch.info') }} - - {% endblock %} - - {% block swag_migration_confirm_language_warning_question %} -

- {{ $tc('swag-migration.index.confirmWarningCard.languageMismatch.question', { targetSystemLanguage }, 0) }} -

- {% endblock %} - - {% block swag_migration_confirm_language_warning_checkbox %} - - {% endblock %} -
- {% endblock %} + + {{ $tc('swag-migration.index.confirmWarningCard.currencyMismatch.text', { sourceSystemCurrency, targetSystemCurrency }, 0) }} + + + + {{ $tc('swag-migration.index.confirmWarningCard.languageMismatch.text', { sourceSystemLanguage, targetSystemLanguage }, 0) }} +
{% endblock %} diff --git a/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-confirm-warning/swag-migration-confirm-warning.scss b/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-confirm-warning/swag-migration-confirm-warning.scss index 55a1b5b9e..828a0bd27 100644 --- a/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-confirm-warning/swag-migration-confirm-warning.scss +++ b/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-confirm-warning/swag-migration-confirm-warning.scss @@ -1,57 +1,10 @@ @import "~scss/variables"; .swag-migration-confirm-warning { - .swag-migration-confirm-warning__card { - text-align: center; - font-size: 14px; - } - - .swag-migration-confirm-warning__bubble { - margin: var(--scale-size-12) auto var(--scale-size-20) auto; - width: var(--scale-size-72); - height: var(--scale-size-72); - border-radius: var(--border-radius-round); - background-color: $color-pumpkin-spice-50; - flex-shrink: 0; - display: flex; - align-items: center; - justify-content: center; - } - - .swag-migration-confirm-warning__bubble-icon { - color: $color-pumpkin-spice-500; - } - - h5.swag-migration-confirm-warning__title { - font-size: 18px; - font-weight: 600; - line-height: 25px; - } - - .swag-migration-confirm-warning__alert { - text-align: center; - display: inline-flex; - } - - .swag-migration-confirm-warning__text { - padding-bottom: var(--scale-size-24); - } - - .swag-migration-confirm-warning__question { - font-weight: 600; - padding-bottom: var(--scale-size-32); - } - - .swag-migration-confirm-warning__checkbox .mt-field--checkbox__content { - display: flex; - justify-content: center; - - .mt-field { - width: auto; - } + max-width: 60rem; + margin: 0 auto; - .mt-field__label label { - flex-grow: 0; - } + .swag-migration-confirm-warning__banner { + margin: 0 auto var(--scale-size-40); } } diff --git a/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-premapping/index.js b/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-premapping/index.js deleted file mode 100644 index aa1cc9f82..000000000 --- a/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-premapping/index.js +++ /dev/null @@ -1,84 +0,0 @@ -import template from './swag-migration-premapping.html.twig'; -import './swag-migration-premapping.scss'; - -const { Component, Store } = Shopware; -const { mapState } = Shopware.Component.getComponentHelper(); -const { debounce } = Shopware.Utils; - -/** - * @private - * @sw-package fundamentals@after-sales - */ -Component.register('swag-migration-premapping', { - template, - - inject: { - /** @var {MigrationApiService} migrationApiService */ - migrationApiService: 'migrationApiService', - }, - - data() { - return { - isLoading: false, - premappingInput: [], - }; - }, - - computed: { - ...mapState(() => Store.get('swagMigration'), [ - 'premapping', - 'dataSelectionIds', - 'isPremappingValid', - ]), - }, - - watch: { - dataSelectionIds() { - this.fetchPremapping(); - }, - }, - - methods: { - fetchPremapping() { - Store.get('swagMigration').setIsLoading(true); - this.isLoading = true; - - return this.migrationApiService.generatePremapping(this.dataSelectionIds) - .then((premapping) => { - Store.get('swagMigration').setPremapping(premapping); - return this.savePremapping(); - }).finally(() => { - Store.get('swagMigration').setIsLoading(false); - this.isLoading = false; - }); - }, - - async savePremapping() { - if (!this.premapping || this.premapping.length === 0) { - return; - } - - const filledOut = this.premapping.every( - (group) => group.mapping.every( - (mapping) => mapping.destinationUuid !== null && - mapping.destinationUuid !== undefined && - mapping.destinationUuid !== '', - ), - ); - - if (!filledOut) { - return; - } - - await this.migrationApiService.writePremapping(this.premapping); - }, - - onPremappingChanged() { - Store.get('swagMigration').setIsLoading(true); - debounce(async () => { - await this.savePremapping(); - Store.get('swagMigration').setIsLoading(false); - }, 500)(); - }, - }, -}); diff --git a/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-premapping/index.ts b/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-premapping/index.ts new file mode 100644 index 000000000..e4c3854e4 --- /dev/null +++ b/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-premapping/index.ts @@ -0,0 +1,101 @@ +import template from './swag-migration-premapping.html.twig'; +import './swag-migration-premapping.scss'; +import type { MigrationPremapping } from '../../../../../type/types'; +import { MIGRATION_API_SERVICE } from '../../../../../core/service/api/swag-migration.api.service'; +import type { MigrationStore } from '../../../store/migration.store'; +import { MIGRATION_STORE_ID } from '../../../store/migration.store'; + +const { Store } = Shopware; +const { mapState } = Shopware.Component.getComponentHelper(); +const { debounce } = Shopware.Utils; + +/** + * @private + */ +export interface SwagMigrationPremappingData { + isLoading: boolean; + migrationStore: MigrationStore; +} + +/** + * @private + * @sw-package fundamentals@after-sales + */ +export default Shopware.Component.wrapComponentConfig({ + template, + + inject: [ + MIGRATION_API_SERVICE, + ], + + data(): SwagMigrationPremappingData { + return { + isLoading: false, + migrationStore: Store.get(MIGRATION_STORE_ID), + }; + }, + + computed: { + ...mapState( + () => Store.get(MIGRATION_STORE_ID), + [ + 'premapping', + 'dataSelectionIds', + ], + ), + }, + + watch: { + dataSelectionIds() { + this.fetchPremapping(); + }, + }, + + methods: { + fetchPremapping() { + this.migrationStore.setIsLoading(true); + this.isLoading = true; + + this.migrationApiService + .generatePremapping(this.dataSelectionIds) + .then(async (premapping: MigrationPremapping[]) => { + this.migrationStore.setPremapping(premapping); + await this.savePremapping(); + }) + .finally(() => { + this.migrationStore.setIsLoading(false); + this.isLoading = false; + }); + }, + + async savePremapping() { + if (!this.premapping || this.premapping.length === 0) { + return; + } + + const filledOut = this.premapping.every((group: MigrationPremapping) => + group.mapping.every( + (mapping) => + mapping.destinationUuid !== null && + mapping.destinationUuid !== undefined && + mapping.destinationUuid !== '', + ), + ); + + if (!filledOut) { + return; + } + + await this.migrationApiService.writePremapping(this.premapping); + }, + + async onPremappingChanged() { + this.migrationStore.setIsLoading(true); + + debounce(async () => { + await this.savePremapping(); + this.migrationStore.setIsLoading(false); + }, 500)(); + }, + }, +}); diff --git a/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-premapping/swag-migration-premapping.html.twig b/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-premapping/swag-migration-premapping.html.twig index 1a32ff1cb..491069bfd 100644 --- a/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-premapping/swag-migration-premapping.html.twig +++ b/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-premapping/swag-migration-premapping.html.twig @@ -1,63 +1,5 @@ {% block swag_migration_premapping %}
- - {% block swag_migration_premapping_unfilled_card %} - - - {% block swag_migration_premapping_unfilled_title %} -
- {{ $tc('swag-migration.index.premappingCard.unfilledTitle') }} -
- {% endblock %} - - {% block swag_migration_premapping_unfilled_caption %} -
- {{ $tc('swag-migration.index.premappingCard.unfilledCaption') }} -
- {% endblock %} - - {% block swag_migration_premapping_unfilled_alert %} - - {{ $tc('swag-migration.index.premappingCard.unfilledAlert') }} - - {% endblock %} -
- {% endblock %} - - {% block swag_migration_premapping_success_card %} - - - {% block swag_migration_premapping_success_bubble %} -
- -
- {% endblock %} - - {% block swag_migration_premapping_success_title %} -
- {{ $tc('swag-migration.index.premappingCard.validTitle') }} -
- {% endblock %} - - {% block swag_migration_premapping_success_caption %} -
- {{ $tc('swag-migration.index.premappingCard.validCaption') }} -
- {% endblock %} -
- {% endblock %} - {% block swag_migration_premapping_unfilled_mapping %} {% endblock %} - - -
- - {% block swag_migration_premapping_loader %} - - {% endblock %} - - {% block swag_migration_premapping_loading_title %} -
- {{ $tc('swag-migration.index.premappingCard.loadingTitle') }} -
- {% endblock %} - - {% block swag_migration_premapping_loading_caption %} -
- {{ $tc('swag-migration.index.premappingCard.loadingCaption') }} -
- {% endblock %} -
-
{% endblock %} diff --git a/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-premapping/swag-migration-premapping.scss b/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-premapping/swag-migration-premapping.scss index 95422f5c1..a59e1503e 100644 --- a/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-premapping/swag-migration-premapping.scss +++ b/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-premapping/swag-migration-premapping.scss @@ -1,57 +1,9 @@ @import "~scss/variables"; .swag-migration-premapping { - .swag-migration-premapping__success-card { - text-align: center; - font-size: 14px; - } - - .swag-migration-premapping__success-bubble { - margin: var(--scale-size-12) auto var(--scale-size-20) auto; - width: var(--scale-size-72); - height: var(--scale-size-72); - border-radius: var(--border-radius-round); - background-color: $color-emerald-50; - flex-shrink: 0; - display: flex; - align-items: center; - justify-content: center; - } - - .swag-migration-premapping__success-icon { - color: $color-emerald-500; - } - - .swag-migration-premapping__success-title { - font-size: 18px; - font-weight: 600; - margin-bottom: 5px; - } - - .swag-migration-premapping__success-caption { - color: $color-gray-500; - margin-bottom: 45px; - } - - .swag-migration-premapping__loading-card { - text-align: center; - font-size: 14px; - } - - .swag-migration-premapping__loading-title { - font-size: 18px; - font-weight: 600; - margin-bottom: 5px; - } - - .swag-migration-premapping__loading-caption { - color: $color-gray-500; - margin-bottom: 45px; - } - .sw-loader.swag-migration-premapping__loader { position: relative; - margin: var(--scale-size-12) auto 42px auto; + margin: var(--scale-size-12) auto var(--scale-size-40) auto; .sw-loader__container { transform: translate(-50%); @@ -59,12 +11,12 @@ } .swag-migration-premapping__alert { - max-width: 800px; + max-width: 60rem; margin-left: auto; margin-right: auto; - @media screen and (max-width: 1360px) { - max-width: 770px; + @media screen and (max-width: 85rem) { + max-width: calc(var(--scale-size-256) * 3); } } @@ -72,33 +24,15 @@ margin-top: var(--scale-size-40); } - .swag-migration-premapping__unfilled-card { - margin-top: var(--scale-size-40); - text-align: center; - font-size: 14px; - } - - .swag-migration-premapping__unfilled-title { - font-size: 18px; - font-weight: 600; - margin-top: var(--scale-size-10); - margin-bottom: 5px; - } - - .swag-migration-premapping__unfilled-caption { - color: $color-gray-500; - margin-bottom: var(--scale-size-10); - } - .swag-migration-premapping__tab-card { - font-size: 14px; + font-size: var(--font-size-xs); } .swag-migration-premapping__tab-card-item { - font-size: 14px; + font-size: var(--font-size-xs); } .sw-grid__cell-label { - font-size: 14px; + font-size: var(--font-size-xs); } -} \ No newline at end of file +} diff --git a/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-progress-bar/index.js b/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-progress-bar/index.ts similarity index 93% rename from src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-progress-bar/index.js rename to src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-progress-bar/index.ts index 0a9973765..14f0fe179 100644 --- a/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-progress-bar/index.js +++ b/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-progress-bar/index.ts @@ -1,13 +1,11 @@ import template from './swag-migration-progress-bar.html.twig'; import './swag-migration-progress-bar.scss'; -const { Component } = Shopware; - /** * @private * @sw-package fundamentals@after-sales */ -Component.register('swag-migration-progress-bar', { +export default Shopware.Component.wrapComponentConfig({ template, props: { diff --git a/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-progress-bar/swag-migration-progress-bar.html.twig b/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-progress-bar/swag-migration-progress-bar.html.twig index 96dcd2448..462449164 100644 --- a/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-progress-bar/swag-migration-progress-bar.html.twig +++ b/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-progress-bar/swag-migration-progress-bar.html.twig @@ -1,6 +1,5 @@ {% block swag_migration_progress_bar %}
- {% block swag_migration_progress_bar_heading %}
{{ title }} @@ -9,10 +8,8 @@ {% block swag_migration_progress_bar %}
- {% block swag_migration_progress_bar_left_point %}
- {% block swag_migration_progress_bar_left_bubble %}
- {% block swag_migration_progress_bar_progress_bar %} - {% block swag_migration_progress_bar_right_bubble %}
Store.get('swagMigration'), [ - 'connectionId', - 'environmentInformation', - 'lastConnectionCheck', - 'adminLocaleLanguage', - 'adminLocaleRegion', - ]), - - displayEnvironmentInformation() { - return this.environmentInformation === null ? {} : - this.environmentInformation; - }, - - migrationRunRepository() { - return this.repositoryFactory.create('swag_migration_run'); - }, - - migrationConnectionRepository() { - return this.repositoryFactory.create('swag_migration_connection'); - }, - - connectionName() { - return this.connection !== null ? - this.connection.name : - this.$tc('swag-migration.index.shopInfoCard.noConnection'); - }, - - shopUrl() { - return this.displayEnvironmentInformation.sourceSystemDomain === undefined ? '' : - this.displayEnvironmentInformation.sourceSystemDomain.replace(/^\s*https?:\/\//, ''); - }, - - shopUrlPrefix() { - if (this.displayEnvironmentInformation.sourceSystemDomain === undefined) { - return ''; - } - - const match = this.displayEnvironmentInformation.sourceSystemDomain.match(/^\s*https?:\/\//); - if (match === null) { - return ''; - } - - return match[0]; - }, - - sslActive() { - return (this.shopUrlPrefix === 'https://'); - }, - - shopUrlPrefixClass() { - return this.sslActive ? 'swag-migration-shop-information__shop-domain-prefix--is-ssl' : ''; - }, - - connectionBadgeLabel() { - if (this.serverUnreachable) { - return 'swag-migration.index.shopInfoCard.serverUnreachable'; - } - - if (this.connected) { - return 'swag-migration.index.shopInfoCard.connected'; - } - - return 'swag-migration.index.shopInfoCard.notConnected'; - }, - - connectionBadgeVariant() { - if (this.connected) { - return BADGE_TYPE.SUCCESS; - } - - return BADGE_TYPE.DANGER; - }, - - shopFirstLetter() { - return this.displayEnvironmentInformation.sourceSystemName === undefined ? 'S' : - this.displayEnvironmentInformation.sourceSystemName[0]; - }, - - profile() { - return this.connection === null || this.connection.profile === undefined ? '' : - // eslint-disable-next-line max-len - `${this.connection.profile.sourceSystemName} ${this.connection.profile.version} - ${this.connection.profile.author}`; - }, - - profileIcon() { - return this.connection === null || - this.connection.profile === undefined || - this.connection.profile.icon === undefined ? null : this.connection.profile.icon; - }, - - gateway() { - return this.connection === null || this.connection.gateway === undefined ? '' : - this.connection.gateway.snippet; - }, - - formattedLastConnectionCheckDate() { - return format.date(this.lastConnectionCheck); - }, - - formattedLastMigrationDateTime() { - return format.date(this.lastMigrationDate); - }, - - assetFilter() { - return Shopware.Filter.getByName('asset'); - }, - - showMoreInformation() { - return this.connection !== null && this.connection !== undefined; - }, - }, - - watch: { - $route: { - immediate: true, - handler() { - this.showResetMigrationConfirmModal = this.$route.meta.resetMigration; - }, - }, - - connectionId: { - immediate: true, - /** - * @param {string} newConnectionId - */ - handler(newConnectionId) { - this.fetchConnection(newConnectionId); - }, - }, - }, - - created() { - this.createdComponent(); - }, - - methods: { - createdComponent() { - this.updateLastMigrationDate(); - }, - - openResetMigrationModal() { - this.showResetMigrationConfirmModal = true; - this.$router.push({ - name: 'swag.migration.index.resetMigration', - }); - }, - - onCloseResetModal() { - this.showResetMigrationConfirmModal = false; - this.$router.push({ - name: 'swag.migration.index.main', - }); - }, - - updateLastMigrationDate() { - const criteria = new Criteria(1, 1); - criteria.addSorting(Criteria.sort('createdAt', 'DESC')); - - return this.migrationRunRepository.search(criteria, this.context).then((runs) => { - if (runs.length > 0) { - this.lastMigrationDate = runs.first().createdAt; - } else { - this.lastMigrationDate = '-'; - } - }); - }, - - /** - * @param {string} connectionId - */ - fetchConnection(connectionId) { - if (!connectionId) { - return Promise.resolve(); - } - - return this.migrationConnectionRepository.get(connectionId, this.context) - .then((connection) => { - if (!connection) { - return Promise.resolve(null); - } - delete connection.credentialFields; - this.connection = connection; - - return this.migrationApiService.getProfileInformation( - connection.profileName, - connection.gatewayName, - ); - }).then((profileInformation) => { - if (!profileInformation) { - return; - } - - this.connection.profile = profileInformation.profile; - this.connection.gateway = profileInformation.gateway; - }); - }, - - onClickEditConnectionCredentials() { - this.$router.push({ - name: 'swag.migration.wizard.credentials', - params: { - connectionId: this.connectionId, - }, - }); - }, - - onClickCreateConnection() { - this.$router.push({ - name: 'swag.migration.wizard.connectionCreate', - }); - }, - - onClickCreateInitialConnection() { - this.$router.push({ - name: 'swag.migration.wizard.introduction', - }); - }, - - onClickSelectConnection() { - this.$router.push({ - name: 'swag.migration.wizard.connectionSelect', - }); - }, - - onClickProfileInstallation() { - this.$router.push({ - name: 'swag.migration.wizard.profileInstallation', - }); - }, - - onClickRemoveConnectionCredentials() { - this.confirmModalIsLoading = true; - return this.migrationApiService.updateConnectionCredentials( - this.connectionId, - { }, - ).then(() => { - this.$router.go(); // Refresh the page - }); - }, - - onClickResetChecksums() { - this.confirmModalIsLoading = true; - return this.migrationApiService.resetChecksums(this.connectionId).then(() => { - this.showResetChecksumsConfirmModal = false; - this.confirmModalIsLoading = false; - }); - }, - - onClickResetMigration() { - this.confirmModalIsLoading = true; - return this.migrationApiService.cleanupMigrationData().then(() => { - this.showResetMigrationConfirmModal = false; - this.confirmModalIsLoading = false; - - this.$nextTick(() => { - this.$router.go(); // reload page - }); - }).catch(() => { - this.showResetMigrationConfirmModal = false; - this.confirmModalIsLoading = false; - - this.createNotificationError({ - title: this.$t( - 'swag-migration.index.shopInfoCard.resetMigrationConfirmDialog.errorNotification.title', - ), - message: this.$t( - 'swag-migration.index.shopInfoCard.resetMigrationConfirmDialog.errorNotification.message', - ), - variant: 'error', - growl: true, - }); - }); - }, - - onClickRefreshConnection() { - return Store.get('swagMigration').init(true); - }, - }, -}); diff --git a/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-shop-information/index.ts b/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-shop-information/index.ts new file mode 100644 index 000000000..9ad8e5158 --- /dev/null +++ b/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-shop-information/index.ts @@ -0,0 +1,484 @@ +import template from './swag-migration-shop-information.html.twig'; +import './swag-migration-shop-information.scss'; +import type { + MigrationConnection, + MigrationProfile, + TEntity, + TEntityCollection, + TRepository, +} from '../../../../../type/types'; +import { MIGRATION_API_SERVICE } from '../../../../../core/service/api/swag-migration.api.service'; +import { MIGRATION_STORE_ID, type MigrationStore } from '../../../store/migration.store'; + +const { Mixin, Store } = Shopware; +const { mapState } = Shopware.Component.getComponentHelper(); +const { format } = Shopware.Utils; +const { Criteria } = Shopware.Data; + +/** + * @private + */ +export const BADGE_TYPE = { + SUCCESS: 'success', + DANGER: 'danger', +} as const; + +const MIGRATION_POLLING_INTERVAL = 2500 as const; + +type PollingType = 'checksum' | 'truncate'; + +/** + * @private + */ +export interface SwagMigrationShopInformationData { + migrationStore: MigrationStore; + confirmModalIsLoading: boolean; + showRemoveCredentialsConfirmModal: boolean; + showResetChecksumsConfirmModal: boolean; + showResetMigrationConfirmModal: boolean; + lastMigrationDate: string; + connection: MigrationConnection | null; + context: unknown; + checksumPollingIntervalId: number | null; + truncatePollingIntervalId: number | null; + isLoading: boolean; +} + +/** + * @private + * @sw-package fundamentals@after-sales + */ +export default Shopware.Component.wrapComponentConfig({ + template, + + inject: [ + MIGRATION_API_SERVICE, + 'repositoryFactory', + 'acl', + ], + + mixins: [ + Mixin.getByName('notification'), + ], + + props: { + connected: { + type: Boolean, + default: false, + }, + }, + + data(): SwagMigrationShopInformationData { + return { + migrationStore: Store.get(MIGRATION_STORE_ID), + checksumPollingIntervalId: null, + truncatePollingIntervalId: null, + confirmModalIsLoading: false, + showRemoveCredentialsConfirmModal: false, + showResetChecksumsConfirmModal: false, + showResetMigrationConfirmModal: false, + lastMigrationDate: '-', + connection: null, + context: Shopware.Context.api, + isLoading: false, + }; + }, + + computed: { + ...mapState( + () => Store.get(MIGRATION_STORE_ID), + [ + 'isResettingChecksum', + 'isTruncatingMigration', + 'connectionId', + 'currentConnection', + 'environmentInformation', + 'lastConnectionCheck', + 'adminLocaleLanguage', + 'adminLocaleRegion', + ], + ), + + migrationRunRepository(): TRepository<'swag_migration_run'> { + return this.repositoryFactory.create('swag_migration_run'); + }, + + migrationConnectionRepository(): TRepository<'swag_migration_connection'> { + return this.repositoryFactory.create('swag_migration_connection'); + }, + + migrationGeneralSettingRepository(): TRepository<'swag_migration_general_setting'> { + return this.repositoryFactory.create('swag_migration_general_setting'); + }, + + displayEnvironmentInformation() { + return this.environmentInformation === null ? {} : this.environmentInformation; + }, + + isUpdating() { + return this.isResettingChecksum || this.isTruncatingMigration || this.isLoading; + }, + + showUpdateBanner() { + return this.isResettingChecksum || this.isTruncatingMigration; + }, + + updateBannerTitle() { + if (this.isResettingChecksum) { + return this.$tc('swag-migration.index.shopInfoCard.updateBanner.isResettingChecksums.title'); + } + + if (this.isTruncatingMigration) { + return this.$tc('swag-migration.index.shopInfoCard.updateBanner.isTruncatingMigration.title'); + } + + return ''; + }, + + updateBannerMessage() { + if (this.isResettingChecksum) { + return this.$tc('swag-migration.index.shopInfoCard.updateBanner.isResettingChecksums.message'); + } + + if (this.isTruncatingMigration) { + return this.$tc('swag-migration.index.shopInfoCard.updateBanner.isTruncatingMigration.message'); + } + + return ''; + }, + + connectionName() { + return this.connection !== null + ? this.connection.name + : this.$tc('swag-migration.index.shopInfoCard.noConnection'); + }, + + connectionBadgeLabel() { + if (this.serverUnreachable) { + return 'swag-migration.index.shopInfoCard.serverUnreachable'; + } + + if (this.connected) { + return 'swag-migration.index.shopInfoCard.connected'; + } + + return 'swag-migration.index.shopInfoCard.notConnected'; + }, + + connectionBadgeVariant() { + if (this.connected) { + return BADGE_TYPE.SUCCESS; + } + + return BADGE_TYPE.DANGER; + }, + + shopUrl() { + return this.displayEnvironmentInformation.sourceSystemDomain === undefined + ? '' + : this.displayEnvironmentInformation.sourceSystemDomain.replace(/^\s*https?:\/\//, ''); + }, + + shopUrlPrefix() { + if (this.displayEnvironmentInformation.sourceSystemDomain === undefined) { + return ''; + } + + const match = this.displayEnvironmentInformation.sourceSystemDomain.match(/^\s*https?:\/\//); + + if (match === null) { + return ''; + } + + return match[0]; + }, + + sslActive() { + return this.shopUrlPrefix === 'https://'; + }, + + shopUrlPrefixClass() { + return this.sslActive ? 'swag-migration-shop-information__shop-domain-prefix--is-ssl' : ''; + }, + + shopFirstLetter() { + return this.displayEnvironmentInformation.sourceSystemName?.charAt(0) ?? 'S'; + }, + + profile() { + return this.connection === null || this.connection.profile === undefined + ? '' + : // eslint-disable-next-line max-len + `${this.connection.profile.sourceSystemName} ${this.connection.profile.version} - ${this.connection.profile.author}`; + }, + + profileIcon() { + return this.connection === null || + this.connection.profile === undefined || + this.connection.profile.icon === undefined + ? null + : this.connection.profile.icon; + }, + + gateway() { + return this.connection === null || this.connection.gateway === undefined ? '' : this.connection.gateway.snippet; + }, + + formattedLastConnectionCheckDate() { + return format.date(this.lastConnectionCheck); + }, + + formattedLastMigrationDateTime() { + return format.date(this.lastMigrationDate); + }, + + assetFilter() { + return Shopware.Filter.getByName('asset'); + }, + + showMoreInformation() { + return this.connection !== null; + }, + }, + + watch: { + $route: { + immediate: true, + handler() { + this.showResetMigrationConfirmModal = this.$route.meta.resetMigration; + }, + }, + + connectionId: { + immediate: true, + handler(newConnectionId: string) { + this.fetchConnection(newConnectionId); + }, + }, + }, + + created() { + this.createdComponent(); + }, + + methods: { + async createdComponent() { + this.isLoading = true; + + try { + const [ + isResettingChecksums, + isTruncatingMigration, + ] = await Promise.all([ + this.migrationApiService.isResettingChecksums(), + this.migrationApiService.isTruncatingMigrationData(), + this.updateLastMigrationDate(), + ]); + + if (isResettingChecksums) { + this.registerPolling('checksum'); + } + + if (isTruncatingMigration) { + this.registerPolling('truncate'); + } + } finally { + this.isLoading = false; + } + }, + + async updateLastMigrationDate() { + const storedRun = Shopware.Store.get(MIGRATION_STORE_ID).latestRun; + + if (storedRun) { + this.lastMigrationDate = storedRun.createdAt; + return Promise.resolve(); + } + + const criteria = new Criteria(1, 1).addSorting(Criteria.sort('createdAt', 'DESC')); + + return this.migrationRunRepository + .search(criteria, this.context) + .then((runs: TEntityCollection<'swag_migration_run'>) => { + if (runs.length > 0) { + this.lastMigrationDate = runs.first().createdAt; + Shopware.Store.get(MIGRATION_STORE_ID).setLatestRun(runs.first()); + } else { + this.lastMigrationDate = '-'; + } + }); + }, + + async fetchConnection(connectionId: string | null) { + if (!connectionId) { + return Promise.resolve(); + } + + if (this.currentConnection) { + this.connection = this.currentConnection; + return Promise.resolve(); + } + + return this.migrationConnectionRepository + .get(connectionId, this.context) + .then((connection: TEntity<'swag_migration_connection'>) => { + if (!connection) { + return Promise.resolve(null); + } + + delete connection.credentialFields; + this.connection = connection; + Shopware.Store.get(MIGRATION_STORE_ID).setCurrentConnection(connection); + + return this.migrationApiService.getProfileInformation(connection.profileName, connection.gatewayName); + }) + .then((profileInformation: MigrationProfile) => { + if (!profileInformation) { + return; + } + + this.connection.profile = profileInformation.profile; + this.connection.gateway = profileInformation.gateway; + }); + }, + + registerPolling(type: PollingType) { + this.unregisterPolling(type); + + if (type === 'checksum') { + this.migrationStore.setIsResettingChecksum(true); + this.checksumPollingIntervalId = setInterval(() => this.poll(type), MIGRATION_POLLING_INTERVAL); + } else { + this.migrationStore.setIsTruncatingMigration(true); + this.truncatePollingIntervalId = setInterval(() => this.poll(type), MIGRATION_POLLING_INTERVAL); + } + }, + + unregisterPolling(type: PollingType) { + if (type === 'checksum') { + if (this.checksumPollingIntervalId) { + clearInterval(this.checksumPollingIntervalId); + } + + this.checksumPollingIntervalId = null; + this.migrationStore.setIsResettingChecksum(false); + } else { + if (this.truncatePollingIntervalId) { + clearInterval(this.truncatePollingIntervalId); + } + + this.migrationStore.setIsTruncatingMigration(false); + this.truncatePollingIntervalId = null; + } + }, + + async poll(type: PollingType) { + const isActive = type === 'checksum' ? this.isResettingChecksum : this.isTruncatingMigration; + + if (!isActive) { + return; + } + + try { + const isStillRunning = + type === 'checksum' + ? await this.migrationApiService.isResettingChecksums() + : await this.migrationApiService.isTruncatingMigrationData(); + + if (!isStillRunning) { + this.unregisterPolling(type); + + if (type === 'truncate') { + await this.migrationStore.init( + this.migrationApiService, + this.migrationGeneralSettingRepository, + true, + ); + } + } + } catch { + this.unregisterPolling(type); + this.createNotificationError({ + title: this.$tc('global.default.error'), + message: this.$tc('swag-migration.api-error.getState'), + }); + } + }, + + openResetMigrationModal() { + this.showResetMigrationConfirmModal = true; + }, + + async onCloseResetModal() { + this.showResetMigrationConfirmModal = false; + await this.$router.push({ + name: 'swag.migration.index.main', + }); + }, + + onClickEditConnectionCredentials() { + this.$router.push({ + name: 'swag.migration.wizard.credentials', + params: { + connectionId: this.connectionId, + }, + }); + }, + + onClickCreateConnection() { + this.$router.push({ + name: 'swag.migration.wizard.connectionCreate', + }); + }, + + onClickCreateInitialConnection() { + this.$router.push({ + name: 'swag.migration.wizard.introduction', + }); + }, + + onClickSelectConnection() { + this.$router.push({ + name: 'swag.migration.wizard.connectionSelect', + }); + }, + + onClickProfileInstallation() { + this.$router.push({ + name: 'swag.migration.wizard.profileInstallation', + }); + }, + + async onClickRefreshConnection() { + await this.migrationStore.init(this.migrationApiService, this.migrationGeneralSettingRepository, true); + }, + + async onClickRemoveConnectionCredentials() { + this.confirmModalIsLoading = true; + + return this.migrationApiService.updateConnectionCredentials(this.connectionId, {}).then(() => { + this.$router.go(); + }); + }, + + async onClickResetChecksums() { + this.confirmModalIsLoading = true; + + await this.migrationApiService.resetChecksums(this.connectionId); + this.registerPolling('checksum'); + + this.showResetChecksumsConfirmModal = false; + this.confirmModalIsLoading = false; + }, + + async onClickResetMigration() { + this.confirmModalIsLoading = true; + + await this.migrationApiService.cleanupMigrationData(); + this.registerPolling('truncate'); + + this.showResetMigrationConfirmModal = false; + this.confirmModalIsLoading = false; + }, + }, +}); diff --git a/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-shop-information/swag-migration-shop-information.html.twig b/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-shop-information/swag-migration-shop-information.html.twig index 4803fd11b..afac4e53f 100644 --- a/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-shop-information/swag-migration-shop-information.html.twig +++ b/src/Resources/app/administration/src/module/swag-migration/component/card/swag-migration-shop-information/swag-migration-shop-information.html.twig @@ -1,52 +1,58 @@ {% block swag_migration_shop_information %} + + {{ updateBannerMessage }} + + -