diff --git a/.githooks/common.sh b/.githooks/common.sh new file mode 100644 index 00000000..a293608e --- /dev/null +++ b/.githooks/common.sh @@ -0,0 +1,79 @@ +#!/bin/bash +# Common utilities and functions for git hooks +# +# Environment variables: +# NO_COLOR - Set to any value to disable colored output (e.g., NO_COLOR=1 git commit) + +# Check if color output is disabled (set NO_COLOR=1 to disable) +: "${NO_COLOR:=}" + +# Initialize branch name from filtered branch list +init_branch_name() { + local list="issue spike task" + local listRE="^($(printf '%s\n' "$list" | tr ' ' '|'))/" + + BRANCH_NAME=$(git branch --show-current | grep -E "$listRE" | sed 's/* //') +} + +# Check if hook should be skipped based on branch, reflog action, or flags +should_skip_hook() { + # Skip on specific branches + if echo "$BRANCH_NAME" | grep -qE '^(hotfix|rebase|prod(uction)?)$'; then + return 0 + fi + + # Skip if Git reflog indicates an amend (reliable for GUI flows) + if [ "${GIT_REFLOG_ACTION:-}" = "commit (amend)" ]; then + return 0 + fi + + # Fallback: check parent process for --no-verify or --amend flags + local ppid_cmd + ppid_cmd=$(ps -ocommand= -p $PPID 2>/dev/null || echo "") + if [[ "$ppid_cmd" == *"--no-verify"* ]] || [[ "$ppid_cmd" == *"--amend"* ]]; then + return 0 + fi + + return 1 +} + +# Print colored status messages (respects NO_COLOR environment variable) +print_header() { + if [ -z "$NO_COLOR" ]; then + printf '\n\033[0;105m%s\033[0m\n' "$1" + else + printf '\n%s\n' "$1" + fi +} + +print_success() { + if [ -z "$NO_COLOR" ]; then + printf '\n\033[0;32m%s\033[0m\n' "$1" + else + printf '\n%s\n' "$1" + fi +} + +print_warning() { + if [ -z "$NO_COLOR" ]; then + printf '\n\033[0;33m%s\033[0m\n' "$1" + else + printf '\n%s\n' "$1" + fi +} + +print_error() { + if [ -z "$NO_COLOR" ]; then + printf '\n\033[0;31m%s\033[0m\n' "$1" + else + printf '\n%s\n' "$1" + fi +} + +print_info() { + if [ -z "$NO_COLOR" ]; then + printf '\033[0;33m%s\033[0m\n' "$1" + else + printf '%s\n' "$1" + fi +} diff --git a/.githooks/post-commit b/.githooks/post-commit index 8312c81c..770a10e0 100755 --- a/.githooks/post-commit +++ b/.githooks/post-commit @@ -5,27 +5,18 @@ # aborted. The hook can be bypassed by using the --no-verify option # when running "git commit". -# ! This could ask for user input to sign the commit as it's now using -# ! the `git commit` command instead of `git commit -m` which is -# ! the default behavior of the `git commit` command. This could be -# ! a problem if the user is not expecting it. This should be fixed -# ! in the future. -if [[ $(ps -ocommand= -p $PPID) == *"git"*"commit"*"--no-verify"* ]] || [[ $(ps -ocommand= -p $PPID) == *"git"*"commit"*"--amend"* ]]; then - printf '\n\033[0;33mSkipping post-commit hook on "%s"... 🀨\033[0m\n' "$BRANCH_NAME" - exit 0 -fi - -list="issue spike task" - -listRE="^($(printf '%s\n' "$list" | tr ' ' '|'))/" +# Source common hook utilities +. "$(dirname "$0")/common.sh" -BRANCH_NAME=$(git branch --show-current | grep -E "$listRE" | sed 's/* //') +# Initialize branch name +init_branch_name -printf '\n\033[0;105mChecking "%s"... \033[0m\n' "$BRANCH_NAME" +print_header "Checking \"$BRANCH_NAME\"..." -if echo "$BRANCH_NAME" | grep -q '^(hotfix)|(rebase)|(production)*$'; then - printf '\n\033[0;33mSkipping post-commit hook on "%s"... 🀨\033[0m\n' "$BRANCH_NAME" - exit 0 +# Skip if on specific branches, or when amending or --no-verify flag is set +if should_skip_hook; then + print_warning "Skipping post-commit hook... 🀨" + exit 0 fi # Check for existence of "new or modified" test files @@ -33,56 +24,47 @@ NEW_TEST_FILES="$(git diff --diff-filter=ACDM --name-only --cached | grep -E '(. # Get all test files to run tests CURRENT_TEST_FILES="$(git ls-files | grep -i -E '(_test\.rb)$')" +RAILS_TEST_EXIT_CODE=0 WORK_DONE=0 -if [ -z "$NEW_TEST_FILES" ]; then - printf '\n\033[0;31mThere are currently no new tests found in "%s". 🀨\033[0m\n' "$BRANCH_NAME" - printf '\n\033[0;31mContinuing without new tests... πŸ˜–\033[0m\n' -fi - if [ -n "$NEW_TEST_FILES" ]; then #Count the number of new test files file_count=$(echo "$NEW_TEST_FILES" | wc -l) # Check if there are any new test files if [ "$file_count" -ne 0 ]; then - printf '\n\033[0;33mFound %d new test files in "%s" πŸŽ‰.\033[0m\n' "$file_count" "$BRANCH_NAME" + print_warning "Found $file_count new test files in \"$BRANCH_NAME\" πŸŽ‰." fi for file in $NEW_TEST_FILES; do # if file is system test file run rake test:system filename if [[ "$file" == *"./test/system/*_test.rb" ]]; then - printf '\n\033[0;33mRunning system test for "%s"...\033[0m\n', "$file" + print_warning "Running system test for \"$file\"..." bundle exec rake test:system "$file" else - printf '\n\033[0;33mRunning unit test on "%s"...\033[0m\n', "$file" + print_warning "Running unit test on \"$file\"..." bundle exec rake test "$file" fi + # Capture the exit code from the test command to determine if it passed or failed + if [ $? -ne 0 ]; then + RAILS_TEST_EXIT_CODE=1 + fi done - RAILS_TEST_EXIT_CODE=$? WORK_DONE=1 -fi - -if [ -n "$CURRENT_TEST_FILES" ] && [ "$WORK_DONE" -eq 0 ]; then - printf '\nRunning all Rails Tests ...\n' +elif [ -n "$CURRENT_TEST_FILES" ]; then + print_warning "No new tests found, running all Rails Tests ..." make test RAILS_TEST_EXIT_CODE=$? WORK_DONE=1 else - RAILS_TEST_EXIT_CODE=0 + print_error "No tests found in \"$BRANCH_NAME\". 🀨" + RAILS_TEST_EXIT_CODE=1 fi if [ ! "$RAILS_TEST_EXIT_CODE" -eq 0 ]; then git reset HEAD~ - printf '\n\033[0;31mCannot commit, tests are failing. Use --no-verify to force commit. πŸ˜–\033[0m\n' + print_error "Cannot commit, tests are failing. Use --no-verify to force commit. πŸ˜–" exit 1 fi -if [ "$WORK_DONE" -eq 1 ]; then - printf '\n\033[0;32mAll tests are green, committing... πŸŽ‰\033[0m\n' - exit 0 -fi - -if [ "$WORK_DONE" -eq 2 ]; then - printf '\n\033[0;41mCurrently skipping broken tests found on "%s". 🀨\033[0m\n' "$BRANCH_NAME" - exit 0 -fi +print_success "All tests are green, committing... πŸŽ‰" +exit 0 diff --git a/.githooks/pre-commit b/.githooks/pre-commit index ffee2218..02d6ab27 100755 --- a/.githooks/pre-commit +++ b/.githooks/pre-commit @@ -3,45 +3,46 @@ # beware if you are in the habit of committing only partial modifications to a file: # THIS HOOK WILL ADD ALL MODIFICATIONS TO A FILE TO THE COMMIT IF ANY FILE WAS CHANGED BY LINTING -list="issue spike task" +# Source common hook utilities +. "$(dirname "$0")/common.sh" -listRE="^($(printf '%s\n' "$list" | tr ' ' '|'))/" +# Initialize branch name +init_branch_name -BRANCH_NAME=$(git branch --show-current | grep -E "$listRE" | sed 's/* //') +print_header "Checking \"$BRANCH_NAME\"..." -printf '\n\033[0;105mChecking "%s"... \033[0m\n' "$BRANCH_NAME" - -if echo "$BRANCH_NAME" | grep -q '^(hotfix)|(rebase)|(production)*$'; then - printf '\n\033[0;33mSkipping pre-commit hook on "%s"... 🀨\033[0m\n' "$BRANCH_NAME" +if should_skip_hook; then + print_success "No checks necessary on \"$BRANCH_NAME\", pushing now... πŸŽ‰" exit 0 fi +# Identify staged Ruby-related files (including Gemfile/Rakefile) to lint before commit. RUBY_FILES="$(git diff --diff-filter=d --name-only --cached | grep -E '(Gemfile|Rakefile|\.(rb|rake|ru))$')" PRE_STATUS="$(git status | wc -l)" +# Initialise exit code variables to track success (0 = success) +RUBOCOP_EXIT_CODE=0 WORK_DONE=0 if [ -z "$RUBY_FILES" ]; then - printf '\n\033[0;31mThere are currently no updated files in "%s". 🀨\033[0m\n' "$BRANCH_NAME" -fi - -if [ -n "$RUBY_FILES" ]; then - printf '\n\033[0;33mRunning Rubocop...\033[0m\n' - for file in $RUBY_FILES; do - git show :"$file" | bundle exec rubocop -a --stdin "$file" - done + print_error "There are currently no updated files in \"$BRANCH_NAME\". 🀨" +else + print_warning "Running Rubocop..." + # Convert space-separated file list into positional parameters for safe argument passing + set -- $RUBY_FILES + # Execute RuboCop with auto-fix enabled on the staged files that have been set + bundle exec rubocop -a --force-exclusion -- "$@" + # Capture the exit code from RuboCop command (0 = success, non-zero = errors) RUBOCOP_EXIT_CODE=$? + # Flag that linting ran so we can report result and re-add files if needed. WORK_DONE=1 -else - printf '\n\033[0;32mContinuing as there are no changes to check... πŸŽ‰\033[0m\n' - RUBOCOP_EXIT_CODE=0 fi POST_STATUS="$(git status | wc -l)" if [ ! $RUBOCOP_EXIT_CODE -eq 0 ]; then git reset HEAD - printf '\n\033[0;31mLinting has uncorrectable errors; please fix and restage your commit. πŸ˜–\033[0m\n' + print_error "Linting has uncorrectable errors; please fix and restage your commit. πŸ˜–" exit 1 fi @@ -49,8 +50,8 @@ if [ "$PRE_STATUS" != "$POST_STATUS" ]; then git add "$RUBY_FILES" fi -if [ $WORK_DONE -eq 1 ]; then - printf '\n\033[0;32mLinting completed successfully! πŸŽ‰\033[0m\n' +if [ ! $WORK_DONE -eq 0 ]; then + print_success "Linting completed successfully! πŸŽ‰" fi exit 0 diff --git a/.githooks/pre-push b/.githooks/pre-push index c871b81b..49bf3725 100755 --- a/.githooks/pre-push +++ b/.githooks/pre-push @@ -1,81 +1,64 @@ #!/bin/bash +# Source common hook utilities +. "$(dirname "$0")/common.sh" + : "${CLIENT_PROFILE:=hmlr}" : "${API_SERVICE_URL:=http://data-api:8080}" : "${RUN_VARS:=--detach --publish}" -# Check if the script is being run in a Git repository -if ! git rev-parse --is-inside-work-tree &>/dev/null; then - printf '\n\033[0;31mThis script must be run inside a Git repository.\033[0m\n' - exit 1 -fi +# Initialize branch name +init_branch_name -# Check if Docker is installed and running -if ! command -v docker &>/dev/null; then - printf '\n\033[0;31mDocker is not installed or not running. Please check Docker and try again.\033[0m\n' - exit 1 -else - DOCKER_SERVER_VERSION=$(docker info -f json | jq -r '.ServerVersion') - if [ $? -eq 0 ]; then - printf "\n\033[0;32mDocker is installed and running at version ${DOCKER_SERVER_VERSION}. Proceeding with the checks... πŸŽ‰\033[0m\n" - else - printf '\n\033[0;31mDocker is installed but not running. Please start Docker and try again.\033[0m\n' - fi -fi +print_header "Checking \"$BRANCH_NAME\"..." -# The branch prefixes are defined in the list variable -# and can be modified as needed. -list="issue spike task" -# The list is converted to a regular expression -listRE="^($(printf '%s\n' "$list" | tr ' ' '|'))/" -# Set the branch name based on the current branch -# The branch name is extracted using grep and sed -# to match the branch prefixes. -BRANCH_NAME=$(git branch --show-current | grep -E "$listRE" | sed 's/* //') -# If the branch name is empty, it means the current branch -# does not match any of the prefixes. -printf '\n\033[0;105mChecking "%s"... \033[0m\n' "$BRANCH_NAME" -# If the branch name is one of the specified prefixes, -# skip the checks and exit with success. -if echo "$BRANCH_NAME" | grep -q '^(hotfix)|(rebase)|(production)*$'; then - printf '\n\033[0;32mNo checks necessary on "%s", skipping hooks... πŸŽ‰\033[0m\n' "$BRANCH_NAME" - exit 0 +# Skip on specific branches, with --no-verify flag, or when amending +if should_skip_hook; then + print_success "Skipping pre-push hook... πŸŽ‰" + exit 0 fi -# Check for existence of "new or modified" files +DOCKER_BUILD_EXIT_CODE=0 +DOCKER_RUN_EXIT_CODE=0 + if ! git update-index -q --ignore-submodules --refresh; then - printf '\n\033[0;31mUp-to-date check failedπŸ˜–\033[0m\n' + print_error "Up-to-date check failed πŸ˜–" DOCKER_BUILD_EXIT_CODE=1 else - printf '\n\033[0;33mBuilding Docker image with "%s" profile... \033[0m\n' "$CLIENT_PROFILE" + print_warning "Building Docker image with \"$CLIENT_PROFILE\" profile... " AWS_PROFILE=$CLIENT_PROFILE make image DOCKER_BUILD_EXIT_CODE=$? fi -# If the Docker image build fails, print an error message and exit with an error code. if [ $DOCKER_BUILD_EXIT_CODE -ne 0 ]; then - printf '\n\033[0;31mDocker image build failed. Please check your changes. πŸ˜–\033[0m\n' + print_error "Docker image build failed. Please check your changes. πŸ˜–" exit 1 -else - printf '\n\033[0;32mDocker image build succeeded. πŸŽ‰\033[0m\n' - CONTAINER_ID=$(make name) - printf '\n\033[0;33mRunning Docker image %s ... \033[0m\n' "$CONTAINER_ID" - AWS_PROFILE=$CLIENT_PROFILE API_SERVICE_URL=$API_SERVICE_URL RUN_VARS=$RUN_VARS make run - secs=5 - while [ $secs -gt -1 ]; do - echo -ne "$secs\033[0K\r" - sleep 1 - : $((secs--)) - done - docker inspect --format="{{.State.Running}}" "$CONTAINER_ID" | grep 'true' -q - DOCKER_RUN_EXIT_CODE=$? - printf '\n\033[0;33mStopping Docker image with exit code %s ... \033[0m\n' "$DOCKER_RUN_EXIT_CODE" - make stop fi +# Build succeeded, now run the container +print_success "Docker image build succeeded. πŸŽ‰" +CONTAINER_ID=$(make name) +print_warning "Running Docker image $CONTAINER_ID ... " +AWS_PROFILE=$CLIENT_PROFILE API_SERVICE_URL=$API_SERVICE_URL RUN_VARS=$RUN_VARS make run + +# Wait for container to stabilize +secs=5 +while [ $secs -gt -1 ]; do + echo -ne "$secs\033[0K\r" + sleep 1 + : $((secs--)) +done + +# Check if container is running +docker inspect --format="{{.State.Running}}" "$CONTAINER_ID" | grep 'true' -q +DOCKER_RUN_EXIT_CODE=$? + +print_warning "Stopping Docker image with exit code $DOCKER_RUN_EXIT_CODE ... " +make stop + if [ $DOCKER_RUN_EXIT_CODE -ne 0 ]; then - printf '\n\033[0;31mDocker image run failed. Please check your changes. πŸ˜–\033[0m\n' + print_error "Docker image run failed. Please check your changes. πŸ˜–" exit 1 else - printf '\n\033[0;32mDocker image run succeeded. πŸŽ‰\033[0m\n' + print_success "Docker image run succeeded. πŸŽ‰" exit 0 fi diff --git a/.gitignore b/.gitignore index dfa99189..56e3cfda 100644 --- a/.gitignore +++ b/.gitignore @@ -94,3 +94,6 @@ vite.config.js.timestamp-*-*.mjs # Ignore local configuration files .env* !.env.development + +# Ignore local TODO files +TODO.md diff --git a/.rubocop.yml b/.rubocop.yml index b778da93..5bc60944 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -28,7 +28,13 @@ Layout/EmptyLinesAroundAttributeAccessor: Enabled: true Layout/SpaceAroundMethodCallOperator: - Enabled: true + EnforcedStyle: compact + +Layout/SpaceAroundBlockParameters: + EnforcedStyle: compact + +Layout/SpaceInsideArrayLiteralBrackets: + EnforcedStyle: compact Lint/DeprecatedOpenSSLConstant: Enabled: true @@ -183,7 +189,7 @@ Style/StringLiterals: EnforcedStyle: single_quotes Style/TrailingCommaInArrayLiteral: - EnforcedStyleForMultiline: comma + EnforcedStyleForMultiline: consistent_comma Style/TrailingCommaInHashLiteral: - EnforcedStyleForMultiline: comma + EnforcedStyleForMultiline: consistent_comma diff --git a/CHANGELOG.md b/CHANGELOG.md index e9548eeb..8973e6e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,8 +8,34 @@ Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +## [2.3.0] - 2026-02 + +### Added + +- Added accredited official statistics logo assets in English and Welsh, with + locale-aware selection + [#571](https://github.com/epimorphics/ukhpi/issues/571) +- Added an accredited official statistics section to the landing page + [#571](https://github.com/epimorphics/ukhpi/issues/571) +- Added Welsh translations for accredited official statistics section + [#571](https://github.com/epimorphics/ukhpi/issues/571) +- Added a development helper script for local start-up +- Build-time version injection via Vite's define configuration, eliminating + runtime HTTP requests for version lookup +- TypeScript declarations for `__APP_VERSION__` global constant in `vite-env.d.ts` + (based on community and documentation recommendations) +- JSDoc documentation for version utilities with type annotations and usage examples +- Enhanced Docker build logging to show `RAILS_ENV` context during asset compilation +- Copy `bin/vite` executable to production Docker stage for Rails/Vite integration +- Added bootsnap to speed up boot time by caching expensive operations + ### Changed +- Refined header and footer styling for better responsiveness and consistency +- Updated cookie banner and skip link spacing for layout consistency +- Improved start-up logging for clearer server boot information +- Improved development hooks for code quality checks +- Updated browser compatibility data dependencies - Refactored application version handling to use build-time injected constants instead of async HTTP requests - Application now uses `__APP_VERSION__` directly in browser code @@ -26,17 +52,6 @@ Versioning](https://semver.org/spec/v2.0.0.html). - Update SPARQL documentation links to use static paths - Set app version to cache in session storage -### Added - -- Build-time version injection via Vite's define configuration, eliminating - runtime HTTP requests for version lookup -- TypeScript declarations for `__APP_VERSION__` global constant in `vite-env.d.ts` - (based on community and documentation recommendations) -- JSDoc documentation for version utilities with type annotations and usage examples -- Enhanced Docker build logging to show `RAILS_ENV` context during asset compilation -- Copy `bin/vite` executable to production Docker stage for Rails/Vite integration -- Added bootsnap to speed up boot time by caching expensive operations - ### Removed - Browser-based async version fetching function and SessionStorage caching for diff --git a/Makefile b/Makefile index 29aeba81..e4571851 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: all assets auth bundles checks clean compiled eject forceclean help image lint locations modules name publish realclean run server start stop tag test test-assets vars version +.PHONY: all assets auth bundles check checks clean compiled coverage eject forceclean help image lint locations modules name publish realclean rubocop run server start stop tag test test-assets update vars version ALPINE_VERSION?=3.22 BUNDLER_VERSION?=$(shell tail -1 Gemfile.lock | tr -d ' ') @@ -15,7 +15,6 @@ PORT?=3002 SHORTNAME?=$(shell echo ${NAME} | cut -f2 -d/) STAGE?=dev -# Please pass in the API_SERVICE_URL from your command line or .env.development file API_SERVICE_URL?=http://localhost:8888 RAILS_RELATIVE_URL_ROOT?=/app/ukhpi RUN_VARS?=-p @@ -42,23 +41,25 @@ ${BUNDLE_CFG}: ${GITHUB_TOKEN} ${GITHUB_TOKEN}: @echo ${PAT} > ${GITHUB_TOKEN} -all: image +all: image ## Default target: build the Docker image -assets: bundles modules compiled +assets: bundles compiled ## Compile static assets for serving @echo vite info @${RAILS} vite:info -auth: ${GITHUB_TOKEN} ${BUNDLE_CFG} +auth: ${GITHUB_TOKEN} ${BUNDLE_CFG} ## Set up authentication for GitHub and Bundler @echo "Authentication set up for GitHub and Bundler." -bundles: +bundles: ## Install Ruby gems via Bundler @echo "Installing Ruby gems via Bundler..." @${BUNDLE} install -checks: lint test +check: checks ## Alias for `checks` target + +checks: lint test ## Run all checks: linting and tests @echo "All checks passed." -clean: +clean: ## Clean up temporary and compiled files @echo "Cleaning up ${SHORTNAME} files..." # Clean up the project @[ -d public/assets ] && ${RAILS} assets:clobber || : @@ -69,78 +70,42 @@ clean: # Remove temporary files and directories @@ rm -rf bundle coverage log node_modules tmp # Remove VCR cassettes to avoid using stale data - @@ rm test/vcr_cassettes/* || : + @make eject -compiled: - @echo "Removing old compiled assets and compiling via vite ..." +compiled: ## Compile assets for production + @echo "Cleaning and precompiling static assets via vite ..." @NODE_OPTIONS=--openssl-legacy-provider ${RAILS} vite:clobber vite:build -eject: +coverage: ## Display test coverage report + @open coverage/index.html + @echo "Displaying test coverage report in browser..." + +eject: ##Remove VCR cassettes to avoid using stale data @echo "Removing VCR Cassettes to avoid stale data..." - @rm -rf test/vcr_cassettes/ + @@ rm test/vcr_cassettes/* || : -eslint: +eslint: ## Run ESLint linting @echo "Running ESLint for ${SHORTNAME} ..." # Lint JavaScript files with ESLint and auto-fix where possible @yarn lint:fix -forceclean: realclean -# Remove all bundled files +forceclean: realclean ## Remove all bundled files @${BUNDLE} clean --force || : -help: - @echo "Make targets:" - @echo " all - build the Docker image (default)" - @echo " assets - install gems and yarn packages, compile assets" - @echo " auth - set up authentication for GitHub and Bundler" - @echo " bundles - install Ruby gems via Bundler" - @echo " checks - run all linting and tests as a single task" - @echo " clean - remove temporary files" - @echo " compiled - remove old compiled assets and compile via vite" - @echo " eject - remove vcr cassettes to avoid stale data" - @echo " eslint - run ESLint on JavaScript files" - @echo " forceclean - remove all generated files including bundled gems" - @echo " help - show this help message" - @echo " image - build the Docker image" - @echo " lint - run linters" - @echo " locations - generate new UKHPI location files" - @echo " modules - install node packages via yarn" - @echo " name - return the image name" - @echo " publish - release the image to the Docker registry" - @echo " realclean - remove all temporary files as well as authentication tokens" - @echo " rubocop - run RuboCop on Ruby files" - @echo " run - run the Docker image with Rails running" - @echo " server - start the Rails server using foreman" - @echo " start - start the Docker container" - @echo " stop - stop the Docker container" - @echo " tag - return a tag string for the current build" - @echo " test - run rails tests" - @echo " test-assets - rebuild assets and run rails tests" - @echo " vars - display all environment variables and their values" - @echo " version - show the current app version" +help: ## Display this message + @echo "Available make targets:" + @grep -hE '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "%-20s %s\n", $$1, $$2}' + @echo "" @echo "" +ifdef AWS_PROFILE @echo "Environment variables (optional: all variables have defaults):" - @echo " ACCOUNT - AWS account ID for ECR (default: from aws cli)" - @echo " ALPINE_VERSION - version of Alpine Linux to use (default: from Dockerfile)" - @echo " AWS_REGION - AWS region for ECR (default: from aws cli)" - @echo " BUNDLER_VERSION - version of Bundler to use (default: from Gemfile.lock)" - @echo " ECR - URL of the ECR registry (default: from aws cli)" - @echo " GPR_OWNER - GitHub owner for the package registry (default: from git config)" - @echo " IMAGE - name of the Docker image (default: ${NAME}:${TAG})" - @echo " API_SERVICE_URL - URL of the FSA Data Dot Food API (default: ${API_SERVICE_URL})" - @echo " NAME - name of the Application (default: from deployment.yaml)" - @echo " NODE_VERSION - version of Node.js to use (default: from .nvmrc)" - @echo " PAT - GitHub personal access token (default: prompt)" - @echo " PORT - port to expose from the Docker container (default: 3000)" - @echo " RUBY_VERSION - version of Ruby to use (default: from .ruby-version)" - @echo " RAILS_RELATIVE_URL_ROOT - relative URL root (default: /catalog)" - @echo " RUN_VARS - additional docker run variables (default: -p)" - @echo " SHORTNAME - short name of the application (default: from NAME)" - @echo " STAGE - deployment stage (default: dev)" - @echo " TAG - tag to apply to the Docker image (default: VERSION_COMMIT_GITHUB_RUN_NUMBER)" - @echo " VERSION - version of the application (default: from VERSION file)" - -image: auth + @make vars +else + @echo "Warning: AWS_PROFILE environment variable is not set. AWS CLI commands may fail." + @echo "Re-run with AWS_PROFILE set to see all variables" +endif + +image: auth ## Build the Docker image @echo Building ${NAME}:${TAG} ... @docker build \ --build-arg ALPINE_VERSION=${ALPINE_VERSION} \ @@ -157,41 +122,41 @@ image: auth . @echo Done. -lint: rubocop eslint +lint: rubocop eslint ## Run linting checks @echo "All linting complete." -locations: +locations: ## Generate UKHPI location files @echo "Generating new UKHPI location files ... " @${RAILS} ukhpi:locations @echo "Done." -modules: +modules: ## Install node modules via yarn @echo "Installing node modules via yarn ..." @yarn install -name: +name: ## Display the shortname of the application @echo ${SHORTNAME} -publish: image +publish: image ## Publish the Docker image to the registry @echo Publishing image: ${REPO}:${TAG} ... @docker tag ${NAME}:${TAG} ${REPO}:${TAG} 2>&1 @docker push ${REPO}:${TAG} 2>&1 @echo Done. -realclean: clean +realclean: clean ## Remove all generated files and authentication @echo "Removing authentication from ${SHORTNAME}..." @rm -f ${GITHUB_TOKEN} ${BUNDLE_CFG} -rubocop: +rubocop: ## Run RuboCop linting @echo "Running RuboCop linting for ${SHORTNAME} ..." # Auto-correct offenses safely where possible with the `-a` flag @${BUNDLE} exec rubocop -a -run: start +run: start ## Run the Docker container locally @if docker network inspect dnet > /dev/null 2>&1; then echo "Using docker network dnet"; else echo "Create docker network dnet"; docker network create dnet; sleep 2; fi @docker run ${RUN_VARS} ${PORT}:3000 --env API_SERVICE_URL=${API_SERVICE_URL} --network dnet --rm --name ${SHORTNAME} ${NAME}:${TAG} -server: start +server: start ## Run the Rails server locally ifdef DEBUG @echo "Starting Rails server in debug mode..."; @echo "Remember to start foreman without the web process: "; @@ -205,33 +170,43 @@ else ${RAILS} server -p ${PORT} -b 0.0.0.0; \ else \ echo "Starting Rails server for development environment..."; \ - exec foreman start -f Procfile.dev -e .env.local,.env.development --color; \ + exec bin/dev -f Procfile.dev -e .env.local,.env.development --color; \ fi endif -start: stop +start: stop ## Start the application @echo "Starting ${SHORTNAME} pointing to ${API_SERVICE_URL} API ..." -stop: +stop: ## Stop the application @echo "Stopping ${SHORTNAME} ..." @docker stop ${SHORTNAME} > /dev/null 2>&1 || : -tag: +tag: ## Display the Docker image tag @echo ${TAG} -test: +test: ## Run unit tests @echo "Running unit tests ..." # Ensure Spring is stopped to avoid stale state during tests @${SPRING} stop # Run Rails tests @${RAILS} test -test-assets: +test-assets: ## Run unit tests with assets rebuilt @echo "Running unit tests with assets rebuilt..." @${VITE} build --clobber --mode=test @${RAILS} test -vars: +update: ## Review and update dependencies interactively + @echo "Checking for outdated dependencies..." + @if [ -f package.json ]; then \ + echo "Running yarn upgrade-interactive..."; \ + yarn upgrade-interactive; \ + fi + @echo "Running bundle outdated to check Ruby gems..." +# Let bundler handle output; treat this as informational even if deps are outdated + @${BUNDLE} outdated --only-explicit || true + +vars: ## Display environment variables @echo "Docker: ${REPO}:${TAG}" @echo "ACCOUNT = ${ACCOUNT}" @echo "ALPINE_VERSION = ${ALPINE_VERSION}" @@ -250,5 +225,5 @@ vars: @echo "TAG = ${TAG}" @echo "VERSION = ${VERSION}" -version: +version: ## Display the application version @echo ${VERSION} diff --git a/app/javascript/images/accredited_official_statistics_logo-cy.png b/app/javascript/images/accredited_official_statistics_logo-cy.png new file mode 100644 index 00000000..b2dbcb19 Binary files /dev/null and b/app/javascript/images/accredited_official_statistics_logo-cy.png differ diff --git a/app/javascript/images/accredited_official_statistics_logo-cy.svg b/app/javascript/images/accredited_official_statistics_logo-cy.svg new file mode 100644 index 00000000..42954b0d --- /dev/null +++ b/app/javascript/images/accredited_official_statistics_logo-cy.svg @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/javascript/images/accredited_official_statistics_logo-en.png b/app/javascript/images/accredited_official_statistics_logo-en.png new file mode 100644 index 00000000..77f14af8 Binary files /dev/null and b/app/javascript/images/accredited_official_statistics_logo-en.png differ diff --git a/app/javascript/images/accredited_official_statistics_logo-en.svg b/app/javascript/images/accredited_official_statistics_logo-en.svg new file mode 100644 index 00000000..22ff1b50 --- /dev/null +++ b/app/javascript/images/accredited_official_statistics_logo-en.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/stylesheets/_cookie-banner.scss b/app/javascript/stylesheets/_cookie-banner.scss index 8a301e38..91253fe7 100644 --- a/app/javascript/stylesheets/_cookie-banner.scss +++ b/app/javascript/stylesheets/_cookie-banner.scss @@ -1,12 +1,13 @@ - @use 'lr-common'; .cookie-banner { font-size: 1.2em; margin: 0 auto; padding: 1rem; + border-bottom: 1px solid lr-common.$lr-green-nav; + box-shadow: 5px 0 -3px 0 lr-common.$lr-green-nav; - & > * + * { + &>*+* { margin-top: 0.5em; } @@ -18,7 +19,7 @@ button { border: none; - padding: 0.25em 0.5em; + padding: 0.5em; } &__accept { diff --git a/app/javascript/stylesheets/_lr-common.scss b/app/javascript/stylesheets/_lr-common.scss index 74419c40..e151fd8a 100644 --- a/app/javascript/stylesheets/_lr-common.scss +++ b/app/javascript/stylesheets/_lr-common.scss @@ -39,7 +39,7 @@ $lr-top-line: $lr-green-nav; $lr-footer-grey: #f0f5f0; $lr-footer-link: color.adjust($lr-separator, $lightness: 10%); $lr-footer-background: #818181; -$lr-green-nav-darkened: color.adjust( $lr-green-nav, $lightness: -20%); +$lr-green-nav-darkened: color.adjust($lr-green-nav, $lightness: -20%); $graph-colours: ( graph-0: $lr-graph-fuschia, @@ -51,7 +51,10 @@ $graph-colours: ( ); /* settings */ -ol, ul, nav ol, nav ul { +ol, +ul, +nav ol, +nav ul { list-style: unset; list-style-type: none; list-style-position: inside; @@ -88,6 +91,7 @@ input[type=radio] { .o-flash-message { padding-top: 3px; padding-bottom: 3px; + p { border-left: 8px solid $lr-yellow; padding-left: 12px; @@ -218,115 +222,36 @@ input[type=radio] { margin-left: 2.5rem; } -// override UK gov stylesheet, which uses the highly specific #global-header selector -#global-header { - &.lr-header, - &.with-proposition { - background-color: white; - - .header-wrapper { - background-color: white; - - .header-proposition { - padding-block-end: 1rem;; - #proposition-name{ - &.lr-header--proposition-name { - color: $lr-link; - } - } - - #proposition-links { - .lr-header--header-proposition--a { - color: $lr-link-quiet; - } - - .lr-header--header-proposition--a__active { - color: $lr-link; - } - - .lr-header--header-proposition { - color: $lr-headline; - } - } - } - - @media screen and (min-width: 769px) { - .header-global, - .header-proposition { - width: unset; - } - .header-proposition { - float: right; - } - } - } - } -} - -.o-container,#content { - max-width: 960px; - margin: 0 15px +.o-container, +#content { + max-width: 960px; + margin: 0 15px } @media (min-width: 641px) { - .o-container,#content { - margin:0 30px - } -} - -@media (min-width: 1020px) { - .o-container,#content { - margin:0 auto - } -} - -#footer { - margin-top: 3rem; - .footer-meta .footer-meta-inner { - width: 100% !important; - } - - .footer-meta a { - text-decoration: underline; - } - - .footer-meta .footer-meta-inner .logo { - position: absolute; - left: 0; - top: 0; - width: 41px; - height: 100%; - } - - .footer-meta .footer-meta-inner .open-government-licence .logo a { - background-image: url('../images/ogl-symbol-41px-black.png'); - display: block; - width: 41px; - height: 17px; - overflow: hidden; - text-indent: -999em; + .o-container, + #content { + margin: 0 30px } +} - .footer-meta .footer-meta-inner .open-government-licence p { - margin: 0; - padding-top: 0.1em; - } +@media (min-width: 1020px) { - .u-muted--footer { - font-size: 11pt ; - color: #444; - margin-top: 1em; + .o-container, + #content { + margin: 0 auto } } + .panel { border: 0; } -:focus, a:focus { +:focus, +a:focus { outline: 2px solid $lr-yellow !important; } - diff --git a/app/javascript/stylesheets/_lr-footer.scss b/app/javascript/stylesheets/_lr-footer.scss new file mode 100644 index 00000000..2ef68b28 --- /dev/null +++ b/app/javascript/stylesheets/_lr-footer.scss @@ -0,0 +1,39 @@ +#footer { + margin-top: 3rem; + + .footer-meta .footer-meta-inner { + width: 100% !important; + } + + .footer-meta a { + text-decoration: underline; + } + + .footer-meta .footer-meta-inner .logo { + position: absolute; + left: 0; + top: 0; + width: 41px; + height: 100%; + } + + .footer-meta .footer-meta-inner .open-government-licence .logo a { + background-image: url('../images/ogl-symbol-41px-black.png'); + display: block; + width: 41px; + height: 17px; + overflow: hidden; + text-indent: -999em; + } + + .footer-meta .footer-meta-inner .open-government-licence p { + margin: 0; + padding-top: 0.1em; + } + + .u-muted--footer { + font-size: 11pt; + color: #444; + margin-top: 1em; + } +} diff --git a/app/javascript/stylesheets/_lr-header.scss b/app/javascript/stylesheets/_lr-header.scss new file mode 100644 index 00000000..2ca9269d --- /dev/null +++ b/app/javascript/stylesheets/_lr-header.scss @@ -0,0 +1,49 @@ +@use "lr-common"; + +// override UK gov stylesheet, which uses the highly specific #global-header selector +#global-header { + + &.lr-header, + &.with-proposition { + background-color: white; + + .header-wrapper { + background-color: white; + + .header-proposition { + #proposition-name { + &.lr-header--proposition-name { + color: lr-common.$lr-link; + } + } + + #proposition-links { + .lr-header--header-proposition--a { + color: lr-common.$lr-link-quiet; + } + + .lr-header--header-proposition--a__active { + color: lr-common.$lr-link; + } + + .lr-header--header-proposition { + color: lr-common.$lr-headline; + } + } + } + + @media screen and (min-width: 769px) { + + .header-global, + .header-proposition { + width: unset; + } + + .header-proposition { + float: right; + } + } + } + } + +} diff --git a/app/javascript/stylesheets/_skip_to_main.scss b/app/javascript/stylesheets/_skip_to_main.scss index 52549069..e81b222b 100644 --- a/app/javascript/stylesheets/_skip_to_main.scss +++ b/app/javascript/stylesheets/_skip_to_main.scss @@ -17,6 +17,9 @@ .c-skip-to-main { background: white; - padding: 1rem; z-index: 9999; + + a { + padding: 1rem; + } } diff --git a/app/javascript/stylesheets/_ukhpi-header.scss b/app/javascript/stylesheets/_ukhpi-header.scss index fbe29940..24ad3e90 100644 --- a/app/javascript/stylesheets/_ukhpi-header.scss +++ b/app/javascript/stylesheets/_ukhpi-header.scss @@ -1,36 +1,114 @@ - @use 'lr-common'; -.c-hmlr-header-colours { - color: lr-common.$lr-black; - background-color: white; -} - #global-header { &.c-hmlr-header { - @extend .c-hmlr-header-colours; + background-color: white; - a, nav { - @extend .c-hmlr-header-colours; + a, + nav { + color: lr-common.$lr-black; } } - .header-wrapper { - @extend .c-hmlr-header-colours; - padding-bottom: 0; - } + &.with-proposition { - .header-proposition #proposition-name { - @extend .c-hmlr-header-colours; - } + .header-wrapper { + padding-bottom: 1rem; + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: flex-end; + height: 200px; + transition: + width 1s, + height 1s; - .header-proposition #proposition-links a { - @extend .c-hmlr-header-colours; - } + @media (min-width: 768px) { + height: 120px; + } + + @media (min-width: 1024px) { + flex-wrap: nowrap; + height: 80px; + } + + .header-global { + flex: 1 0 auto; + order: 1; + margin-right: auto; + align-content: flex-start; + + @media (min-width: 1024px) { + align-content: flex-end; + } + + .header-logo { + .content { + img { + height: 40px; + margin-top: 14px; + } + } + } + } - .header-wrapper .header-global .header-logo .content img { - margin-top: 14px; - height: 40px; + .header-proposition { + flex: 3 1 100%; + order: 3; + align-content: flex-end; + padding-bottom: 0; + + @media (min-width: 1024px) { + order: 2; + flex: 0 0 auto; + width: auto; + } + + .content { + @media (min-width: 768px) { + margin: unset; + margin-left: auto; + width: fit-content; + } + + #proposition-name, + #proposition-links a { + color: lr-common.$lr-black; + } + + #proposition-links { + @media (max-width: 767px) { + display: flex; + flex-wrap: wrap; + align-items: stretch; + + li { + align-self: flex-end; + } + } + } + } + } + + .accredited-statistic-logo { + flex: 0 0 auto; + order: 2; + display: inline-block; + margin-left: auto; + margin-top: 0; + vertical-align: middle; + align-content: flex-end; + + @media (min-width: 1024px) { + order: 3; + margin-right: 1rem; + } + + img { + height: 6rem; + } + } + } } } diff --git a/app/javascript/stylesheets/application.scss b/app/javascript/stylesheets/application.scss index 59e7c66f..bc3b40ba 100644 --- a/app/javascript/stylesheets/application.scss +++ b/app/javascript/stylesheets/application.scss @@ -16,6 +16,8 @@ /* Other required styles - original order maintained to avoid conflicts */ @import '@/stylesheets/simple-tables'; @import '@/stylesheets/lr-common'; +@import '@/stylesheets/lr-header'; +@import '@/stylesheets/lr-footer'; @import '@/stylesheets/print'; @import '@/stylesheets/ukhpi-header'; @import '@/stylesheets/ukhpi-typography'; diff --git a/app/lib/version.rb b/app/lib/version.rb index 0e20a671..e6c9cef4 100644 --- a/app/lib/version.rb +++ b/app/lib/version.rb @@ -1,7 +1,7 @@ module Version MAJOR = 2 - MINOR = 2 - PATCH = 2 + MINOR = 3 + PATCH = 0 SUFFIX = nil VERSION = "#{MAJOR}.#{MINOR}.#{PATCH}#{SUFFIX && ".#{SUFFIX}"}".freeze end diff --git a/app/views/common/_accredited_statistic_logo.html.haml b/app/views/common/_accredited_statistic_logo.html.haml new file mode 100644 index 00000000..078e78df --- /dev/null +++ b/app/views/common/_accredited_statistic_logo.html.haml @@ -0,0 +1,7 @@ +.accredited-statistic-logo + = link_to("#{root_path(lang: I18n.locale)}#accredited-statistics", + class: 'content', + title: t('common.header.accredited_statistic')) do + = vite_image_tag("images/accredited_official_statistics_logo-#{I18n.locale}.png", + srcset: vite_asset_path("images/accredited_official_statistics_logo-#{I18n.locale}.svg"), + alt: t('common.header.accredited_statistic')) diff --git a/app/views/common/_header.html.haml b/app/views/common/_header.html.haml index 65c99ee8..5b8ea621 100644 --- a/app/views/common/_header.html.haml +++ b/app/views/common/_header.html.haml @@ -5,6 +5,7 @@ = link_to(root_path(lang: I18n.locale), class: 'content', title: t('common.header.home_link')) do = vite_image_tag('images/ukhpi-icon.png', srcset: vite_asset_path('images/ukhpi-icon.svg'), alt: 'UKHPI Logo') + = render partial: 'common/accredited_statistic_logo' .header-proposition .content = link_to(t('common.header.menu_text'), '#proposition-links', class: 'menu sr-only') @@ -25,6 +26,8 @@ %li = link_to(t('action.changelog'), changelog_index_path(lang: I18n.locale), class: active_class(changelog_index_path)) + + .o-lr-top-bar .container.o-container diff --git a/app/views/landing/_index_cy.html.haml b/app/views/landing/_index_cy.html.haml index 0803f282..5a61665b 100644 --- a/app/views/landing/_index_cy.html.haml +++ b/app/views/landing/_index_cy.html.haml @@ -50,9 +50,17 @@ = link_to "fodel atchweliad hedonig", "//cy.ons.gov.uk/economy/inflationandpriceindices/methodologies/developmentofasingleofficialhousepriceindex?:uri=economy/inflationandpriceindices/methodologies/developmentofasingleofficialhousepriceindex" ar gyfer y ffynonellau data amrywiol ar brisiau a nodweddion eiddo i gynhyrchu amcangyfrifon o’r newid yn y prisiau tai ar gyfer pob cyfnod. + + %p#accredited-statistics + Adolygwyd yr ystadegau swyddogol achrededig hyn yn annibynnol gan y Swyddfa + Rheoleiddio Ystadegau ym Medi 2018. Maent yn cydymffurfio Ò’r safonau dibynadwyaeth, + ansawdd a gwerth yn y Cod Ymarfer ar gyfer Ystadegau a dylid eu labelu’n + β€˜ystadegau swyddogol achrededig’. + %p Cyhoeddir y mynegai bob mis, gyda ffigurau Gogledd Iwerddon yn cael eu diweddaru bob chwarter. + %p Cynghorir y gall nifer isel o drafodion gwerthu mewn rhai awdurdodau lleol arwain at anwadalrwydd yn yr amcangyfrifon ar y lefelau hyn. Dylid dadansoddi ardaloedd daearyddol @@ -60,6 +68,7 @@ hytrach na chanolbwyntio ar symudiadau misol. Ceir rhagor o fanylion ar ein = link_to('tudalen cyfarwyddyd', '//www.gov.uk/government/publications/about-the-uk-house-price-index.cy') am ein data a’u hansawdd. + %p Mae data hanesyddol o fewn y teclyn hwn yn ddata deilliedig. O dan Fynegai Prisiau Tai y DU, mae data ar gael o 1995 ar gyfer Cymru a Lloegr, o 2004 ar gyfer yr Alban ac o 2005 ar diff --git a/app/views/landing/_index_en.html.haml b/app/views/landing/_index_en.html.haml index 851fdaad..5b5dcc6e 100644 --- a/app/views/landing/_index_en.html.haml +++ b/app/views/landing/_index_en.html.haml @@ -54,6 +54,12 @@ to the various sources of data on property price and attributes to produce estimates of the change in house prices each period. + %p#accredited-statistics + These accredited official statistics were independently reviewed by the Office + for Statistics Regulation in September 2018. They comply with the standards + of trustworthiness, quality and value in the Code of Practice for Statistics + and should be labelled ‘accredited official statistics’. + %p The index is published monthly, with Northern Ireland figures updated quarterly. diff --git a/bin/dev b/bin/dev new file mode 100755 index 00000000..3bf4d524 --- /dev/null +++ b/bin/dev @@ -0,0 +1,23 @@ +#!/usr/bin/env sh + +export PORT="${PORT:-3000}" + +if command -v overmind 1> /dev/null 2>&1 +then + overmind start -f Procfile.dev "$@" + exit $? +fi + +if command -v hivemind 1> /dev/null 2>&1 +then + echo "Hivemind is installed. Running the application with Hivemind..." + exec hivemind Procfile.dev "$@" + exit $? +fi + +if gem list --no-installed --exact --silent foreman; then + echo "Installing foreman..." + gem install foreman +fi + +foreman start -f Procfile "$@" diff --git a/config/application.rb b/config/application.rb index d0de9d86..8bed5516 100644 --- a/config/application.rb +++ b/config/application.rb @@ -58,12 +58,14 @@ module Command # :nodoc: class ServerCommand def print_boot_information(server, url) - msg = { + msg = "Starting #{server} Rails #{Rails.version} in #{Rails.env}" + msg += " on #{url}" if url + info = { ts: DateTime.now.utc.strftime('%FT%T.%3NZ'), level: 'INFO', - message: "Starting #{server} Rails #{Rails.version} in #{Rails.env} #{url}", + message: msg, } - say msg.to_json + say info.to_json end end end diff --git a/config/locales/cy.yml b/config/locales/cy.yml index 29f0a5a9..4d1c984b 100644 --- a/config/locales/cy.yml +++ b/config/locales/cy.yml @@ -6,6 +6,7 @@ cy: app_title: "Mynegai Prisiau Tai y DU" beta_tag: "[cy] BETA" feedback_request: "Problem neu awgrym? Bydd eich adborth yn ein helpu i wella’r gwasanaeth hwn." + accredited_statistic: "Ystadegau Swyddogol Achrededig" cookie_banner: heading: "Mae’r wefan hon yn defnyddio cwcis" diff --git a/config/locales/en.yml b/config/locales/en.yml index cd466b9d..e41db8a8 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -6,6 +6,7 @@ en: app_title: "UK House Price Index" beta_tag: "BETA" feedback_request: "Found a problem or have a suggestion? Your feedback will help us to improve this service." + accredited_statistic: "Official Accredited Statistic" cookie_banner: heading: "This site uses cookies" diff --git a/yarn.lock b/yarn.lock index 408c8e23..a964dc80 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2097,11 +2097,11 @@ __metadata: linkType: hard "baseline-browser-mapping@npm:^2.9.0": - version: 2.9.4 - resolution: "baseline-browser-mapping@npm:2.9.4" + version: 2.9.19 + resolution: "baseline-browser-mapping@npm:2.9.19" bin: baseline-browser-mapping: dist/cli.js - checksum: 10c0/5f33f2505130a234d70b332e3dbedf79655fa2be8287c4f4ea2dd0caca9e1c0c2598d8f5c3798e632382404a414de2b47710ec06b6741deb5e1236eb0b62803b + checksum: 10c0/569928db78bcd081953d7db79e4243a59a579a34b4ae1806b9b42d3b7f84e5bc40e6e82ae4fa06e7bef8291bf747b33b3f9ef5d3c6e1e420cb129d9295536129 languageName: node linkType: hard @@ -2227,17 +2227,10 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.30001688, caniuse-lite@npm:^1.0.30001702": - version: 1.0.30001734 - resolution: "caniuse-lite@npm:1.0.30001734" - checksum: 10c0/5869cb6a01e7a012a8c5d7b0482e2c910be3a2a469d4ef516a54db3f846fbaedb2600eeaa270dae9e2ad9328e33f39782e6f459405fcca620021f5f06694542d - languageName: node - linkType: hard - -"caniuse-lite@npm:^1.0.30001759": - version: 1.0.30001759 - resolution: "caniuse-lite@npm:1.0.30001759" - checksum: 10c0/b0f415960ba34995cda18e0d25c4e602f6917b9179290a76bdd0311423505b78cc93e558a90c98a22a1cc6b1781ab720ef6beea24ec7e29a1c1164ca72eac3a2 +"caniuse-lite@npm:^1.0.30001688, caniuse-lite@npm:^1.0.30001702, caniuse-lite@npm:^1.0.30001759": + version: 1.0.30001767 + resolution: "caniuse-lite@npm:1.0.30001767" + checksum: 10c0/37067c6d2b26623f81494a1f206adbff2b80baed3318ba430684e428bd7d81be889f39db8ef081501d1db5f7dd5d15972892f173eb59c9f3bb780e0b38e6610a languageName: node linkType: hard