diff --git a/.circleci/config.yml b/.circleci/config.yml index c191f31..ade8260 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -5,24 +5,24 @@ jobs: environment: RAILS_ENV: test docker: - - image: cimg/ruby:3.3.0-node + - image: cimg/ruby:3.3.4-node environment: PGHOST: localhost PGUSER: buildlight RAILS_ENV: test - - image: postgres:10.1-alpine + - image: postgres:16-alpine environment: POSTGRES_USER: buildlight POSTGRES_DB: buildlight_test - POSTGRES_PASSWORD: "" + POSTGRES_PASSWORD: "correcthorsebatterystaple" steps: - checkout - run: echo -e "export RAILS_ENV=test\nexport RACK_ENV=test" >> $BASH_ENV - run: 'bundle check --path=vendor/bundle || bundle install --path=vendor/bundle --jobs=4 --retry=3 ' - run: - name: Install Yarn Dependencies - command: yarn install --cache-folder ~/.yarn-cache + name: Install NPM Dependencies + command: npm install - run: |- mkdir -p config && echo 'test: database: buildlight_test @@ -30,11 +30,12 @@ jobs: encoding: unicode pool: 15 username: buildlight + password: correcthorsebatterystaple host: localhost ' > config/database.yml - run: command: bundle exec bin/setup - run: - command: yarn build:css + command: npm run build:css - run: command: bundle exec rake diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..9612375 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,37 @@ +# See https://docs.docker.com/engine/reference/builder/#dockerignore-file for more about ignoring files. + +# Ignore git directory. +/.git/ + +# Ignore bundler config. +/.bundle + +# Ignore all environment files (except templates). +/.env* +!/.env*.erb + +# Ignore all default key files. +/config/master.key +/config/credentials/*.key + +# Ignore all logfiles and tempfiles. +/log/* +/tmp/* +!/log/.keep +!/tmp/.keep + +# Ignore pidfiles, but keep the directory. +/tmp/pids/* +!/tmp/pids/.keep + +# Ignore storage (uploaded files in development and any SQLite databases). +/storage/* +!/storage/.keep +/tmp/storage/* +!/tmp/storage/.keep + +# Ignore assets. +/node_modules/ +/app/assets/builds/* +!/app/assets/builds/.keep +/public/assets diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c6b89e7..eeeab33 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,20 +40,20 @@ jobs: with: bundler-cache: true - - uses: actions/cache@v4 + - name: Set up Node + uses: actions/setup-node@v4 with: - path: ~/.yarn-cache - key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} - restore-keys: | - ${{ runner.os }}-yarn- - - name: Yarn Install - run: yarn install --cache-folder ~/.yarn-cache + node-version-file: 'package.json' + cache: 'npm' + + - name: NPM Install + run: npm ci - name: App Setup run: bin/setup - name: Build CSS - run: yarn build:css + run: npm run build:css - name: Standard run: bundle exec rake standard diff --git a/.github/workflows/fly-deploy.yml b/.github/workflows/fly-deploy.yml new file mode 100644 index 0000000..b0c246e --- /dev/null +++ b/.github/workflows/fly-deploy.yml @@ -0,0 +1,18 @@ +# See https://fly.io/docs/app-guides/continuous-deployment-with-github-actions/ + +name: Fly Deploy +on: + push: + branches: + - main +jobs: + deploy: + name: Deploy app + runs-on: ubuntu-latest + concurrency: deploy-group # optional: ensure only one action runs at a time + steps: + - uses: actions/checkout@v4 + - uses: superfly/flyctl-actions/setup-flyctl@master + - run: flyctl deploy --remote-only + env: + FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} diff --git a/.node-version b/.node-version new file mode 100644 index 0000000..58a1f09 --- /dev/null +++ b/.node-version @@ -0,0 +1 @@ +22.4.0 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..e1fadd8 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,104 @@ +# syntax = docker/dockerfile:1 + +# Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile +ARG RUBY_VERSION=3.3.4 +FROM --platform=linux/amd64 ruby:$RUBY_VERSION-alpine as base + +LABEL fly_launch_runtime="rails" + +# Rails app lives here +WORKDIR /rails + +# Set production environment +ENV BUNDLE_DEPLOYMENT="1" \ + BUNDLE_PATH="/usr/local/bundle" \ + BUNDLE_WITHOUT="development:test" \ + RAILS_ENV="production" + +# Update gems and bundler +RUN gem update --system --no-document && \ + gem install -N bundler + +# Install packages +RUN apk update && \ + apk add tzdata && \ + rm -rf /var/cache/apk/* + + +# Throw-away build stages to reduce size of final image +FROM base as prebuild + +# Install packages needed to build gems and node modules +RUN apk update && \ + apk add build-base curl git gyp libpq-dev pkgconfig python3 + + +FROM prebuild as node + +# Install Node.js +ARG NODE_VERSION=22.4.0 +ENV PATH=/usr/local/node/bin:$PATH +RUN curl -sL https://unofficial-builds.nodejs.org/download/release/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64-musl.tar.gz | tar xz -C /tmp/ && \ + mkdir /usr/local/node && \ + cp -rp /tmp/node-v${NODE_VERSION}-linux-x64-musl/* /usr/local/node/ && \ + rm -rf /tmp/node-v${NODE_VERSION}-linux-x64-musl + +# Install node modules +COPY --link package.json package-lock.json ./ +RUN npm install + + +FROM prebuild as build + +# Install application gems +COPY --link Gemfile Gemfile.lock ./ +RUN bundle install && \ + bundle exec bootsnap precompile --gemfile && \ + rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git + +# Copy node modules +COPY --from=node /rails/node_modules /rails/node_modules +COPY --from=node /usr/local/node /usr/local/node +ENV PATH=/usr/local/node/bin:$PATH + +# Copy application code +COPY --link . . + +# Precompile bootsnap code for faster boot times +RUN bundle exec bootsnap precompile app/ lib/ + +# Adjust binfiles to set current working directory +RUN grep -l '#!/usr/bin/env ruby' /rails/bin/* | xargs sed -i '/^#!/aDir.chdir File.expand_path("..", __dir__)' + +# Precompiling assets for production without requiring secret RAILS_MASTER_KEY +RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile + + +# Final stage for app image +FROM base + +# Install packages needed for deployment +RUN apk update && \ + apk add curl gzip jemalloc libpq postgresql-client && \ + rm -rf /var/cache/apk/* + +# Copy built artifacts: gems, application +COPY --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}" +COPY --from=build /rails /rails + +# Run and own only the runtime files as a non-root user for security +RUN addgroup --system --gid 1000 rails && \ + adduser --system rails --uid 1000 --ingroup rails --home /home/rails --shell /bin/sh rails && \ + chown -R 1000:1000 db log tmp +USER 1000:1000 + +# Deployment options +ENV LD_PRELOAD="libjemalloc.so.2" \ + MALLOC_CONF="dirty_decay_ms:1000,narenas:2,background_thread:true" + +# Entrypoint sets up the container. +ENTRYPOINT ["/rails/bin/docker-entrypoint"] + +# Start the server by default, this can be overwritten at runtime +EXPOSE 3000 +CMD ["./bin/rails", "server"] diff --git a/Gemfile b/Gemfile index 74465b0..5a15939 100644 --- a/Gemfile +++ b/Gemfile @@ -1,11 +1,12 @@ source "https://rubygems.org" -ruby "3.3.0" +ruby "3.3.4" gem "rails", "~> 7.1.3" gem "pg" gem "bootsnap" +gem "dockerfile-rails" gem "honeybadger" gem "particlerb" gem "puma" @@ -18,10 +19,6 @@ gem "propshaft" # https://github.com/faye/websocket-driver-ruby/pull/85 gem "websocket-driver", github: "danielmorrison/websocket-driver-ruby", branch: "support-frozen-by-default" -group :production do - gem "lograge" -end - group :development, :test do gem "debug" gem "factory_bot_rails" diff --git a/Gemfile.lock b/Gemfile.lock index cfec339..e7323ab 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -100,6 +100,8 @@ GEM irb (~> 1.10) reline (>= 0.3.8) diff-lcs (1.5.1) + dockerfile-rails (1.6.17) + rails (>= 3.0.0) drb (2.2.1) erubi (1.12.0) factory_bot (6.4.6) @@ -150,11 +152,6 @@ GEM json (2.7.2) language_server-protocol (3.17.0.3) lint_roller (1.1.0) - lograge (0.14.0) - actionpack (>= 4) - activesupport (>= 4) - railties (>= 4) - request_store (~> 1.0) loofah (2.22.0) crass (~> 1.0.2) nokogiri (>= 1.12.0) @@ -183,6 +180,12 @@ GEM nokogiri (1.16.5) mini_portile2 (~> 2.8.2) racc (~> 1.4) + nokogiri (1.16.5-aarch64-linux) + racc (~> 1.4) + nokogiri (1.16.5-arm64-darwin) + racc (~> 1.4) + nokogiri (1.16.5-x86_64-linux) + racc (~> 1.4) parallel (1.25.1) parser (3.3.4.0) ast (~> 2.4.1) @@ -245,8 +248,6 @@ GEM regexp_parser (2.9.2) reline (0.5.8) io-console (~> 0.5) - request_store (1.6.0) - rack (>= 1.4) rexml (3.3.2) strscan rspec (3.13.0) @@ -326,17 +327,21 @@ GEM zeitwerk (2.6.15) PLATFORMS + aarch64-linux + arm64-darwin ruby + x86_64-linux + x86_64-linux-musl DEPENDENCIES bootsnap cssbundling-rails debug + dockerfile-rails factory_bot_rails figaro honeybadger importmap-rails - lograge particlerb pg propshaft @@ -350,7 +355,7 @@ DEPENDENCIES websocket-driver! RUBY VERSION - ruby 3.3.0p0 + ruby 3.3.4p94 BUNDLED WITH - 2.5.7 + 2.5.17 diff --git a/Procfile.dev b/Procfile.dev index 0c4b735..c086f6a 100644 --- a/Procfile.dev +++ b/Procfile.dev @@ -1,2 +1,2 @@ web: bin/rails server -p 3000 -css: yarn build:css --watch +css: npm run build:css -- --watch diff --git a/bin/docker-entrypoint b/bin/docker-entrypoint new file mode 100755 index 0000000..b75c109 --- /dev/null +++ b/bin/docker-entrypoint @@ -0,0 +1,5 @@ +#!/bin/sh -e + +# Add any container initialization steps here + +exec "${@}" diff --git a/bin/yarn b/bin/yarn deleted file mode 100755 index 460dd56..0000000 --- a/bin/yarn +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env ruby -APP_ROOT = File.expand_path('..', __dir__) -Dir.chdir(APP_ROOT) do - begin - exec "yarnpkg", *ARGV - rescue Errno::ENOENT - $stderr.puts "Yarn executable was not detected in the system." - $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install" - exit 1 - end -end diff --git a/config/application.rb b/config/application.rb index 886f47d..8c2eec7 100644 --- a/config/application.rb +++ b/config/application.rb @@ -1,6 +1,19 @@ require_relative "boot" -require "rails/all" +require "rails" + +# Pick the frameworks you want: +require "active_model/railtie" +require "active_job/railtie" +require "active_record/railtie" +# require "active_storage/engine" +require "action_controller/railtie" +require "action_mailer/railtie" +# require "action_mailbox/engine" +# require "action_text/engine" +require "action_view/railtie" +require "action_cable/engine" +# require "rails/test_unit/railtie" # Require the gems listed in Gemfile, including any gems # you've limited to :test, :development, or :production. diff --git a/config/dockerfile.yml b/config/dockerfile.yml new file mode 100644 index 0000000..c60fcf1 --- /dev/null +++ b/config/dockerfile.yml @@ -0,0 +1,18 @@ +# generated by dockerfile-rails + +--- +options: + alpine: true + bin-cd: true + gemfile-updates: false + jemalloc: true + label: + fly_launch_runtime: rails + parallel: true + platform: linux/amd64 + prepare: false + packages: + build: + - git + deploy: + - gzip diff --git a/config/environments/development.rb b/config/environments/development.rb index 2e7fb48..768920d 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -34,7 +34,7 @@ end # Store uploaded files on the local file system (see config/storage.yml for options). - config.active_storage.service = :local + # config.active_storage.service = :local # Don't care if the mailer can't send. config.action_mailer.raise_delivery_errors = false diff --git a/config/environments/production.rb b/config/environments/production.rb index f3e1b71..c87acc9 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -37,7 +37,7 @@ # config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for NGINX # Store uploaded files on the local file system (see config/storage.yml for options). - config.active_storage.service = :local + # config.active_storage.service = :local # Mount Action Cable outside main process or domain. # config.action_cable.mount_path = nil diff --git a/config/environments/test.rb b/config/environments/test.rb index adbb4a6..6049334 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -35,7 +35,7 @@ config.action_controller.allow_forgery_protection = false # Store uploaded files on the local file system in a temporary directory. - config.active_storage.service = :test + # config.active_storage.service = :test config.action_mailer.perform_caching = false diff --git a/config/routes.rb b/config/routes.rb index b9ebd55..a774ef8 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,8 @@ Rails.application.routes.draw do + # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500. + # Can be used by load balancers and uptime monitors to verify that the app is live. + get "up" => "rails/health#show", :as => :rails_health_check + # use a namespace to avoid resources colliding with usernames namespace :api do resources :devices, only: :show diff --git a/fly.toml b/fly.toml new file mode 100644 index 0000000..6b59dfc --- /dev/null +++ b/fly.toml @@ -0,0 +1,38 @@ +# fly.toml app configuration file generated for buildlight on 2024-08-01T14:11:40-04:00 +# +# See https://fly.io/docs/reference/configuration/ for information about how to use this file. +# + +app = 'buildlight' +primary_region = 'iad' +console_command = '/rails/bin/rails console' + +[build] + +[deploy] + release_command = './bin/rails db:migrate' + +[env] + HOST = 'buildlight.collectiveidea.com' + PORT = '8080' + RUBYOPT = '--enable=frozen-string-literal' + +[http_service] + internal_port = 8080 + force_https = true + auto_stop_machines = 'stop' + auto_start_machines = true + min_machines_running = 1 + processes = ['app'] + + [[http_service.checks]] + grace_period = '10s' + interval = '30s' + method = 'GET' + timeout = '2s' + path = '/up' + +[[vm]] + memory = '256mb' + cpu_kind = 'shared' + cpus = 1 diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..46db3f5 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,199 @@ +{ + "name": "app", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "app", + "dependencies": { + "sass": "^1.77.8" + }, + "engines": { + "node": "^22.0.0" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "license": "MIT", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/immutable": { + "version": "4.3.4", + "license": "MIT" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/sass": { + "version": "1.77.8", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.8.tgz", + "integrity": "sha512-4UHg6prsrycW20fqLGPShtEvo/WyHRVRHwOP4DzkUrObWoWI05QBSfzU71TVB7PFaL104TwNaHpjlWXAZbQiNQ==", + "license": "MIT", + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + } + } +} diff --git a/package.json b/package.json index 3f80457..792826c 100644 --- a/package.json +++ b/package.json @@ -2,8 +2,10 @@ "name": "app", "private": "true", "dependencies": { - "sass": "^1.77.8", - "yarn": "^1.22.22" + "sass": "^1.77.8" + }, + "engines": { + "node": "^22.0.0" }, "scripts": { "build:css": "sass ./app/assets/stylesheets/application.sass.scss ./app/assets/builds/application.css --no-source-map --load-path=node_modules" diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index 0dbabf2..0000000 --- a/yarn.lock +++ /dev/null @@ -1,129 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -anymatch@~3.1.2: - version "3.1.3" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" - integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== - -braces@~3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" - integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== - dependencies: - fill-range "^7.1.1" - -"chokidar@>=3.0.0 <4.0.0": - version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -fill-range@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" - integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== - dependencies: - to-regex-range "^5.0.1" - -fsevents@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" - integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== - -glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -immutable@^4.0.0: - version "4.3.4" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.4.tgz#2e07b33837b4bb7662f288c244d1ced1ef65a78f" - integrity sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA== - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-glob@^4.0.1, is-glob@~4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -picomatch@^2.0.4, picomatch@^2.2.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - -sass@^1.77.8: - version "1.77.8" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.77.8.tgz#9f18b449ea401759ef7ec1752a16373e296b52bd" - integrity sha512-4UHg6prsrycW20fqLGPShtEvo/WyHRVRHwOP4DzkUrObWoWI05QBSfzU71TVB7PFaL104TwNaHpjlWXAZbQiNQ== - dependencies: - chokidar ">=3.0.0 <4.0.0" - immutable "^4.0.0" - source-map-js ">=0.6.2 <2.0.0" - -"source-map-js@>=0.6.2 <2.0.0": - version "1.0.2" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" - integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -yarn@^1.22.22: - version "1.22.22" - resolved "https://registry.yarnpkg.com/yarn/-/yarn-1.22.22.tgz#ac34549e6aa8e7ead463a7407e1c7390f61a6610" - integrity sha512-prL3kGtyG7o9Z9Sv8IPfBNrWTDmXB4Qbes8A9rEzt6wkJV8mUvoirjU0Mp3GGAU06Y0XQyA3/2/RQFVuK7MTfg==