diff --git a/.env.example b/.env.example index 7ee505d9..8362fe62 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,5 @@ # Hostname of the application -APP_HOST=templatus.test +APP_HOST=templatus-inertia.test # Timezone TIME_ZONE=Berlin diff --git a/.env.test b/.env.test index 0194a966..00ef28f8 100644 --- a/.env.test +++ b/.env.test @@ -1 +1 @@ -APP_HOST=templatus.test +APP_HOST=templatus-inertia.test diff --git a/.eslintignore b/.eslintignore index 9dd10973..6b119bf6 100644 --- a/.eslintignore +++ b/.eslintignore @@ -6,3 +6,8 @@ /log /db /config +*.config.js +*.config.ts +.eslintrc.js +app/javascript/routes.js +app/javascript/routes.d.ts diff --git a/.eslintrc.js b/.eslintrc.js index c51507e3..6d27db93 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,44 +1,4 @@ module.exports = { root: true, - env: { - browser: true, - jest: true, - node: true, - }, - plugins: [], - extends: [ - 'eslint:recommended', - 'plugin:@typescript-eslint/recommended', - 'plugin:jest/recommended', - 'plugin:vue/base', - 'plugin:vue/vue3-essential', - 'plugin:vue/vue3-recommended', - 'plugin:vue/vue3-strongly-recommended', - 'prettier', - 'plugin:prettier/recommended', - ], - globals: { - defineProps: 'readonly', - defineEmits: 'readonly', - defineExpose: 'readonly', - withDefaults: 'readonly', - }, - rules: { - '@typescript-eslint/no-unused-vars': [ - 'error', - { - argsIgnorePattern: '^_', - }, - ], - '@typescript-eslint/no-var-requires': 'off', - 'vue/no-v-html': 'off', - 'vue/script-setup-uses-vars': 'error', - 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', - 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', - }, - parserOptions: { - parser: '@typescript-eslint/parser', // the typescript-parser for eslint, instead of tslint - sourceType: 'module', // allow the use of imports statements - ecmaVersion: 2020, // allow the parsing of modern ecmascript - }, + extends: '@feltcoop', }; diff --git a/.prettierrc.json b/.prettierrc.json index 78d6b4db..0adfaa51 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -3,5 +3,9 @@ "singleQuote": true, "rubyPlugins": "plugin/single_quotes,plugin/trailing_comma", "printWidth": 80, - "tabWidth": 2 + "tabWidth": 2, + "svelteAllowShorthand": true, + "svelteSortOrder": "scripts-markup-styles", + "svelteStrictMode": false, + "plugins": ["prettier-plugin-svelte"] } diff --git a/.rubocop.yml b/.rubocop.yml index fbc8fe83..dfcc8189 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -89,6 +89,9 @@ Style/StringLiterals: Style/StringLiteralsInInterpolation: EnforcedStyle: single_quotes +Style/DisableCopsWithinSourceCodeDirective: + Enabled: false + ### Metrics Metrics/BlockLength: diff --git a/.vscode/settings.json b/.vscode/settings.json index eae324a0..39d68a60 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -18,7 +18,7 @@ "**/node_modules": true }, - "eslint.validate": ["javascript", "vue"], + "eslint.validate": ["javascript"], "ruby.lint": { "rubocop": { diff --git a/Dockerfile b/Dockerfile index 739ff074..41a2851b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ FROM ghcr.io/ledermann/rails-base-builder:3.1.2-alpine AS Builder # Remove some files not needed in resulting image. # Because they are required for building the image, they can't be added to .dockerignore -RUN rm -r package.json yarn.lock tsconfig.json tailwind.config.js postcss.config.js vite.config.ts +RUN rm -r package.json yarn.lock tsconfig.json tailwind.config.js postcss.config.js vite.config.ts svelte.config.js cypress.config.ts FROM ghcr.io/ledermann/rails-base-final:3.1.2-alpine LABEL maintainer="georg@ledermann.dev" diff --git a/Gemfile b/Gemfile index 41a82777..b2964604 100644 --- a/Gemfile +++ b/Gemfile @@ -9,6 +9,9 @@ gem 'rails', '~> 7.0.3' # Use Vite in Rails and bring joy to your JavaScript experience (https://github.com/ElMassimo/vite_ruby) gem 'vite_rails' +# Inertia adapter for Rails (https://github.com/inertiajs/inertia-rails) +gem 'inertia_rails' + # Pg is the Ruby interface to the PostgreSQL RDBMS (https://github.com/ged/ruby-pg) gem 'pg', '~> 1.1' @@ -39,6 +42,9 @@ gem 'rack-brotli' # Simple, efficient background processing for Ruby (https://sidekiq.org) gem 'sidekiq' +# Brings Rails named routes to javascript (http://github.com/railsware/js-routes) +gem 'js-routes' + group :development, :test do # Debugging functionality for Ruby (https://github.com/ruby/debug) gem 'debug', platforms: %i[mri mingw x64_mingw] diff --git a/Gemfile.lock b/Gemfile.lock index 9c5caff8..d71185ce 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -114,9 +114,13 @@ GEM honeybadger (4.12.1) i18n (1.10.0) concurrent-ruby (~> 1.0) + inertia_rails (1.12.1) + rails (>= 5) io-console (0.5.11) irb (1.4.1) reline (>= 0.3.0) + js-routes (2.2.4) + railties (>= 4) listen (3.7.1) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) @@ -323,6 +327,8 @@ DEPENDENCIES dotenv-rails guard-rspec honeybadger + inertia_rails + js-routes lograge pg (~> 1.1) prettier_print diff --git a/README.md b/README.md index 096b2be7..0c8e6190 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,20 @@ -[![Build Status](https://github.com/ledermann/templatus/workflows/CI/badge.svg)](https://github.com/ledermann/templatus/actions) +[![Build Status](https://github.com/ledermann/templatus-inertia/workflows/CI/badge.svg)](https://github.com/ledermann/templatus-inertia/actions) [![Cypress](https://img.shields.io/endpoint?url=https://dashboard.cypress.io/badge/simple/5d6bqs&style=flat-square&logo=cypress)](https://dashboard.cypress.io/projects/5d6bqs/runs) -# Templatus (Vue edition) +# Templatus (Inertia edition) -Templatus is an opinionated template to build web applications with Ruby on Rails and Vue.js 3. It simplifies the process of setting up a new application while following best practices. +Templatus is an opinionated template to build web applications with Ruby on Rails and Inertia (using Svelte.js). It simplifies the process of setting up a new application while following best practices. -Live demo available at https://templatus.ledermann.dev +Live demo available at https://templatus-inertia.ledermann.dev -There is a sister repository that uses Hotwire instead of Vue.js: +There are two sister repositories: + +Using Hotwire instead of Inertia (the "DHH way"): https://github.com/ledermann/templatus-hotwire/ +Using API instead of Inertia and Svelte.js instead of Vue.js; +https://github.com/ledermann/templatus/ + ## Features / Technology stack ### Backend @@ -23,13 +28,10 @@ https://github.com/ledermann/templatus-hotwire/ ### Frontend -- [Vite](https://vitejs.dev/) for bundling JavaScript and CSS with Hot Module Replacement (HMR) in development -- [Vue 3](https://v3.vuejs.org/) as frontend framework -- [Vue Router 4](https://next.router.vuejs.org/) for frontend routing -- [Pinia](https://pinia.esm.dev/) for frontend state management +- [Inertia](https://inertiajs.com/) as a protocol for frontend/backend communication - [Tailwind CSS 3](https://tailwindcss.com/) to not have to write CSS at all -- [Heroicons](https://heroicons.com/) for SVG icons as Vue components -- [Rails Request.JS](https://github.com/rails/request.js) for AJAX requests with default headers +- [Tabler Icons](https://tablericons.com/) for free SVG icons +- [Vite](https://vitejs.dev/) for bundling JavaScript and CSS with Hot Module Replacement (HMR) in development ### Development @@ -44,7 +46,6 @@ https://github.com/ledermann/templatus-hotwire/ - [RuboCop](https://rubocop.org/) for Ruby static code analysis - [RSpec](https://rspec.info/) for Ruby testing - [ESLint](https://eslint.org/) for TypeScript static code analysis -- [Jest](https://jestjs.io/) for TypeScript unit testing - [Cypress](https://www.cypress.io/) for E2E testing ### Deployment @@ -62,7 +63,6 @@ https://github.com/ledermann/templatus-hotwire/ - [Lograge](https://github.com/roidrage/lograge) for single-line logging - Gzip and Brotli compression of dynamic responses (HTML, JSON) using [Rack::Deflater](https://github.com/rack/rack/blob/master/lib/rack/deflater.rb), [Rack::Brotli](https://github.com/marcotc/rack-brotli) - Fine-tuned Content Security Policy (CSP) -- Ready for PWA (manifest, service-worker) ## Metrics @@ -76,35 +76,30 @@ This template is developed with optimized performance and security in mind. The ### Security headers -[![Security headers](docs/security-headers.png)](https://securityheaders.com/?q=templatus.ledermann.dev&followRedirects=on) +[![Security headers](docs/security-headers.png)](https://securityheaders.com/?q=templatus-inertia.ledermann.dev&followRedirects=on) What's the red _Permissions-Policy_ badge? This seems to be fixed with one of the next Rails update: https://github.com/rails/rails/pull/41994 ### Mozilla Observatory -[![Mozilla Observatory](docs/mozilla-observatory.png)](https://observatory.mozilla.org/analyze/templatus.ledermann.dev) +[![Mozilla Observatory](docs/mozilla-observatory.png)](https://observatory.mozilla.org/analyze/templatus-inertia.ledermann.dev) ### WebPageTest -[![WebPageTest](docs/web-page-test.png)](https://www.webpagetest.org/result/220603_AiDcD6_63C/) +[![WebPageTest](docs/web-page-test.png)](https://www.webpagetest.org/result/220530_BiDcQQ_83b754931114d99469b521e72731eb4d/) ### GTmetrix -[![GTmetrix](docs/GTmetrix.png)](https://gtmetrix.com/reports/templatus.ledermann.dev/OsUlXu9V/) +[![GTmetrix](docs/GTmetrix.png)](https://gtmetrix.com/reports/templatus-inertia.ledermann.dev/OsUlXu9V/) ### Check-your-website -[![Check-your-website](docs/check-your-website.png)](https://check-your-website.server-daten.de/?q=templatus.ledermann.dev) +[![Check-your-website](docs/check-your-website.png)](https://check-your-website.server-daten.de/?q=templatus-inertia.ledermann.dev) ### JavaScript size -147 KB of compiled JavaScript (after tree-shaking, minified & uncompressed). The largest parts are: - -- Vue.js + Vue Router (75 KB) -- Honeybadger (23 KB) -- ActionCable (9 KB) -- Pinia (6 KB) +165 KB of compiled JavaScript (after tree-shaking, minified & uncompressed). ``` $ RAILS_ENV=production bin/rails assets:precompile @@ -115,41 +110,41 @@ success Already up-to-date. Building with Vite ⚡️ vite v2.9.10 building for production... transforming... -✓ 298 modules transformed. +✓ 155 modules transformed. rendering chunks... -../../public/vite/assets/logo.44ced38d.svg 0.48 KiB +../../public/vite/assets/logo.10f03a2b.svg 0.48 KiB ../../public/vite/manifest-assets.json 0.22 KiB ../../public/vite/manifest.json 0.32 KiB -../../public/vite/assets/application.46f860cd.js 16.18 KiB / gzip: 6.58 KiB -../../public/vite/assets/application.46f860cd.js.map 25.15 KiB -../../public/vite/assets/application.97255384.css 19.66 KiB / gzip: 4.69 KiB -../../public/vite/assets/vendor.bc768583.js 130.42 KiB / gzip: 48.90 KiB -../../public/vite/assets/vendor.bc768583.js.map 979.48 KiB -Build with Vite complete: /Users/ledermann/Projects/templatus/public/vite +../../public/vite/assets/application.5e23928d.js 27.28 KiB / gzip: 10.26 KiB +../../public/vite/assets/application.5e23928d.js.map 49.74 KiB +../../public/vite/assets/application.a344bc09.css 18.45 KiB / gzip: 4.47 KiB +../../public/vite/assets/vendor.b59622b9.js 137.75 KiB / gzip: 48.35 KiB +../../public/vite/assets/vendor.b59622b9.js.map 555.30 KiB +Build with Vite complete: /Users/ledermann/Projects/templatus-inertia/public/vite ``` ### Network transfer -Small footprint: The demo application transfers only **62 KB** of data on the first visit. +Small footprint: The demo application transfers only **72 KB** of data on the first visit. ![Network](docs/network.png) ### Docker build time -With multi-stage building and using [DockerRailsBase](https://github.com/ledermann/docker-rails-base) the build of the Docker image takes very little time. Currently, the build job requires about 1,5 minutes on GitHub Actions (see https://github.com/ledermann/templatus/actions) +With multi-stage building and using [DockerRailsBase](https://github.com/ledermann/docker-rails-base) the build of the Docker image takes very little time. Currently, the `deploy` job requires about 1,5 minutes on GitHub Actions (see https://github.com/ledermann/templatus-inertia/actions) ### Docker image size -The Docker image is based on Alpine Linux and is optimized for minimal size (currently **113 MB** uncompressed disk size). It includes just the bare minimum - no build tools like Node.js, no JS sources (just the compiled assets), no tests. +The Docker image is based on Alpine Linux and is optimized for minimal size (currently **115 MB** uncompressed disk size). It includes just the bare minimum - no build tools like Node.js, no JS sources (just the compiled assets), no tests. ``` -$ container-diff analyze ghcr.io/ledermann/templatus -n +$ container-diff analyze ghcr.io/ledermann/templatus-inertia -n -----Size----- -Analysis for ghcr.io/ledermann/templatus: -IMAGE DIGEST SIZE -ghcr.io/ledermann/templatus sha256:... 114.9M +Analysis for ghcr.io/ledermann/templatus-inertia: +IMAGE DIGEST SIZE +ghcr.io/ledermann/templatus-inertia sha256:... 114.7M ``` ## Getting started @@ -159,8 +154,8 @@ ghcr.io/ledermann/templatus sha256:... 114.9M 1. Clone the repo locally: ```bash -git clone git@github.com:ledermann/templatus.git -cd templatus +git clone git@github.com:ledermann/templatus-inertia.git +cd templatus-inertia ``` 2. Install PostgreSQL, Redis, and puma-dev (if not already present). On a Mac with Homebrew, run this to install from the `Brewfile`: @@ -178,7 +173,7 @@ puma-dev link # Use Vite via puma-dev proxy # Adopted from https://github.com/puma/puma-dev#webpack-dev-server -echo 3036 > ~/.puma-dev/vite.templatus +echo 3036 > ~/.puma-dev/vite.templatus-inertia ``` 4. Setup the application to install gems and NPM packages and create the database: @@ -193,7 +188,7 @@ bin/setup bin/dev ``` -Then open https://templatus.test in your browser. +Then open https://templatus-inertia.test in your browser. ### Running linters diff --git a/app/controllers/about_controller.rb b/app/controllers/about_controller.rb new file mode 100644 index 00000000..7e208521 --- /dev/null +++ b/app/controllers/about_controller.rb @@ -0,0 +1,5 @@ +class AboutController < ApplicationController + def show + render inertia: 'About/Show', props: { features: Features.new.data } + end +end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 09705d12..79e252bf 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,2 +1,3 @@ class ApplicationController < ActionController::Base + include InertiaErrors end diff --git a/app/controllers/clicks_controller.rb b/app/controllers/clicks_controller.rb index d03e354a..0f326304 100644 --- a/app/controllers/clicks_controller.rb +++ b/app/controllers/clicks_controller.rb @@ -1,13 +1,8 @@ class ClicksController < ApplicationController def index clicks = Click.order(created_at: :desc).limit(5).to_a - return unless stale?(clicks, template: false, public: true) - expires_in 0, must_revalidate: true - - respond_to do |format| - format.json { render json: { total: Click.count, items: clicks } } - end + render inertia: 'Clicks/Index', props: { total: Click.count, items: clicks } end def create @@ -15,6 +10,8 @@ def create Click.create! user_agent: request.user_agent, ip: anonymize(request.remote_ip) ActionCable.server.broadcast 'clicks_channel', click + + render inertia: 'Clicks/Index' end private diff --git a/app/controllers/concerns/inertia_errors.rb b/app/controllers/concerns/inertia_errors.rb new file mode 100644 index 00000000..0755448c --- /dev/null +++ b/app/controllers/concerns/inertia_errors.rb @@ -0,0 +1,11 @@ +require 'active_support/concern' + +module InertiaErrors + extend ActiveSupport::Concern + + included do + rescue_from ActiveRecord::RecordNotFound do + render inertia: 'Error/Show', props: { status: 404 }, status: :not_found + end + end +end diff --git a/app/controllers/exceptions_controller.rb b/app/controllers/exceptions_controller.rb new file mode 100644 index 00000000..bdf812f1 --- /dev/null +++ b/app/controllers/exceptions_controller.rb @@ -0,0 +1,14 @@ +class ExceptionsController < ActionController::Base + # Don't raise InvalidCrossOriginRequest for requesting not existing JavaScript file + skip_after_action :verify_same_origin_request + + def show + status = request.path_info.delete_prefix('/').to_i + + if request.format.html? || request.inertia? + render inertia: 'Error/Show', props: { status: }, status: status + else + head status + end + end +end diff --git a/app/controllers/vue_controller.rb b/app/controllers/vue_controller.rb deleted file mode 100644 index f8726c9e..00000000 --- a/app/controllers/vue_controller.rb +++ /dev/null @@ -1,4 +0,0 @@ -class VueController < ApplicationController - def index - end -end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 25619933..de6be794 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,45 +1,2 @@ module ApplicationHelper - def versions - { - alpine: alpine_version, - ruby: ruby_version, - rails: rails_version, - puma: puma_version, - postgres: postgres_version, - redis: redis_version, - sidekiq: sidekiq_version, - } - end - - private - - def alpine_version - return unless RUBY_PLATFORM.include?('linux') - - `cat /etc/alpine-release 2>/dev/null`.chomp - end - - def ruby_version - RUBY_VERSION - end - - def rails_version - Rails.version - end - - def puma_version - Puma::Const::PUMA_VERSION - end - - def postgres_version - ActiveRecord::Base.connection.select_value('SHOW server_version;') - end - - def redis_version - Redis.new.info['redis_version'] - end - - def sidekiq_version - Sidekiq::VERSION - end end diff --git a/app/javascript/channels/index.js b/app/javascript/channels/index.js index 298a304d..43b3652f 100644 --- a/app/javascript/channels/index.js +++ b/app/javascript/channels/index.js @@ -1,5 +1,4 @@ // Load all the channels within this directory and all subdirectories. // Channel files must be named *_channel.js. -const channels = require.context('.', true, /_channel\.js$/); -channels.keys().forEach(channels); +import.meta.globEager('./**/*_channel.js'); diff --git a/app/javascript/components/AppBackground.svelte b/app/javascript/components/AppBackground.svelte new file mode 100644 index 00000000..21e633ca --- /dev/null +++ b/app/javascript/components/AppBackground.svelte @@ -0,0 +1,33 @@ + + + diff --git a/app/javascript/components/AppFooter.svelte b/app/javascript/components/AppFooter.svelte new file mode 100644 index 00000000..c0ac2056 --- /dev/null +++ b/app/javascript/components/AppFooter.svelte @@ -0,0 +1,55 @@ + + + diff --git a/app/javascript/components/AppHeader.svelte b/app/javascript/components/AppHeader.svelte new file mode 100644 index 00000000..e0270dd6 --- /dev/null +++ b/app/javascript/components/AppHeader.svelte @@ -0,0 +1,39 @@ + + +
+ Logo + + +
diff --git a/app/javascript/components/ClickButton.svelte b/app/javascript/components/ClickButton.svelte new file mode 100644 index 00000000..c67ea765 --- /dev/null +++ b/app/javascript/components/ClickButton.svelte @@ -0,0 +1,34 @@ + + +
+
+ {#key count} +
+ {count.toLocaleString()} +
+ {/key} +
Clicks
+
+ + + + +
diff --git a/app/javascript/components/ClickList.svelte b/app/javascript/components/ClickList.svelte new file mode 100644 index 00000000..69a3b6c3 --- /dev/null +++ b/app/javascript/components/ClickList.svelte @@ -0,0 +1,44 @@ + + + diff --git a/app/javascript/components/GitVersion.svelte b/app/javascript/components/GitVersion.svelte new file mode 100644 index 00000000..9a60d0eb --- /dev/null +++ b/app/javascript/components/GitVersion.svelte @@ -0,0 +1,20 @@ + + +
+ {commitVersion} + +
diff --git a/app/javascript/components/PageTitle.svelte b/app/javascript/components/PageTitle.svelte new file mode 100644 index 00000000..016a9e2e --- /dev/null +++ b/app/javascript/components/PageTitle.svelte @@ -0,0 +1,5 @@ +

+ +

diff --git a/app/javascript/entrypoints/application.css b/app/javascript/entrypoints/application.css index 9eab8194..55710b0b 100644 --- a/app/javascript/entrypoints/application.css +++ b/app/javascript/entrypoints/application.css @@ -5,7 +5,7 @@ :root { --color-rails-light: theme('colors.rails.light'); --color-rails-dark: theme('colors.rails.dark'); - --color-vue: theme('colors.vue.DEFAULT'); + --color-inertia: theme('colors.inertia.DEFAULT'); } .gradient__rails-light { @@ -16,6 +16,6 @@ stop-color: var(--color-rails-dark); } -.gradient__vue { - stop-color: var(--color-vue); +.gradient__inertia { + stop-color: var(--color-inertia); } diff --git a/app/javascript/entrypoints/application.ts b/app/javascript/entrypoints/application.ts index e28f2dc6..b4393e71 100644 --- a/app/javascript/entrypoints/application.ts +++ b/app/javascript/entrypoints/application.ts @@ -1,63 +1,3 @@ -import { createApp } from 'vue'; -import { createPinia } from 'pinia'; -import { metaContent } from '@/utils/metaContent'; -import router from '@/router'; -import App from '@/App.vue'; -import HoneybadgerVue from '@honeybadger-io/vue'; -import plausible from '@/plugins/plausible'; -import { register } from 'register-service-worker'; - -register('/sw.js', { - registrationOptions: { scope: './' }, - ready(_registration: ServiceWorkerRegistration) { - console.log('Service worker is active.'); - }, - registered(_registration: ServiceWorkerRegistration) { - console.log('Service worker has been registered.'); - }, - cached(_registration: ServiceWorkerRegistration) { - console.log('Content has been cached for offline use.'); - }, - updatefound(_registration: ServiceWorkerRegistration) { - console.log('New content is downloading.'); - }, - updated(_registration: ServiceWorkerRegistration) { - console.log('New content is available; please refresh.'); - }, - offline() { - console.log( - 'No internet connection found. App is running in offline mode.', - ); - }, - error(error) { - console.error('Error during service worker registration:', error); - }, -}); - -document.addEventListener('DOMContentLoaded', () => { - const app = createApp(App); - - const honeybadgerApiKey = metaContent('honeybadger-api-key'); - if (honeybadgerApiKey) { - const gitCommitVersion = metaContent('git-commit-version'); - - app.use(HoneybadgerVue, { - apiKey: honeybadgerApiKey, - environment: 'production', - revision: gitCommitVersion, - }); - } - - app.use(router); - app.use(createPinia()); - - const plausibleUrl = metaContent('plausible-url'); - if (plausibleUrl) - app.use(plausible, { - domain: metaContent('app-host'), - hashMode: true, - apiHost: plausibleUrl, - }); - - app.mount('#vue-app'); -}); +import '../utils/setupHoneybadger.ts'; +import '../utils/setupInertia.ts'; +import '../utils/setupPlausible.ts'; diff --git a/app/javascript/images/logo.svg b/app/javascript/images/logo.svg index 9762c8e9..cf3b07de 100644 --- a/app/javascript/images/logo.svg +++ b/app/javascript/images/logo.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/app/javascript/layouts/default.svelte b/app/javascript/layouts/default.svelte new file mode 100644 index 00000000..e48cbf74 --- /dev/null +++ b/app/javascript/layouts/default.svelte @@ -0,0 +1,23 @@ + + +
+ + + + +
+ +
+ + +
diff --git a/app/javascript/pages/About/Show.svelte b/app/javascript/pages/About/Show.svelte new file mode 100644 index 00000000..ad590be1 --- /dev/null +++ b/app/javascript/pages/About/Show.svelte @@ -0,0 +1,74 @@ + + + + +About + +

+ Templatus is an opinionated template for web applications with + Ruby on Rails and Inertia +

+ +
+ {#each features as group} +
+
+

+ {group.slogan} +

+

+ {group.name} +

+
+
+
+ {#each group.items as feature} +
+
+ + +

+ + {feature.name} + + + {#if feature.version} + + {feature.version} + + {/if} +

+
+
+ {@html feature.description} +
+
+ {/each} +
+
+
+ {/each} +
diff --git a/app/javascript/pages/Clicks/Index.svelte b/app/javascript/pages/Clicks/Index.svelte new file mode 100644 index 00000000..32f8554a --- /dev/null +++ b/app/javascript/pages/Clicks/Index.svelte @@ -0,0 +1,58 @@ + + + + +
+ Hello, Templatus! + +

+ Templatus is an opinionated template for web applications with + Ruby on Rails and Inertia +

+
+ + + +{#if $currentItems.length} +

+ Latest clicks +

+ + +{/if} diff --git a/app/javascript/pages/Error/Show.svelte b/app/javascript/pages/Error/Show.svelte new file mode 100644 index 00000000..38742607 --- /dev/null +++ b/app/javascript/pages/Error/Show.svelte @@ -0,0 +1,22 @@ + + + + +Error {status} + +

+ {ERROR_MESSAGES[status] || 'Unknown Error'} +

diff --git a/app/javascript/routes.d.ts b/app/javascript/routes.d.ts new file mode 100644 index 00000000..42d29a35 --- /dev/null +++ b/app/javascript/routes.d.ts @@ -0,0 +1,118 @@ +/** + * File generated by js-routes RubyVariables.GEM_VERSION + * Based on Rails RubyVariables.RAILS_VERSION routes of RubyVariables.APP_CLASS + */ +declare type Optional = { + [P in keyof T]?: T[P] | null; +}; +declare type BaseRouteParameter = string | boolean | Date | number; +declare type MethodRouteParameter = BaseRouteParameter | (() => BaseRouteParameter); +declare type ModelRouteParameter = { + id: MethodRouteParameter; +} | { + to_param: MethodRouteParameter; +} | { + toParam: MethodRouteParameter; +}; +declare type RequiredRouteParameter = BaseRouteParameter | ModelRouteParameter; +declare type OptionalRouteParameter = undefined | null | RequiredRouteParameter; +declare type QueryRouteParameter = OptionalRouteParameter | QueryRouteParameter[] | { + [k: string]: QueryRouteParameter; +}; +declare type RouteParameters = Record; +declare type Serializable = Record; +declare type Serializer = (value: Serializable) => string; +declare type RouteHelperExtras = { + requiredParams(): string[]; + toString(): string; +}; +declare type RequiredParameters = T extends 1 ? [RequiredRouteParameter] : T extends 2 ? [RequiredRouteParameter, RequiredRouteParameter] : T extends 3 ? [RequiredRouteParameter, RequiredRouteParameter, RequiredRouteParameter] : T extends 4 ? [ + RequiredRouteParameter, + RequiredRouteParameter, + RequiredRouteParameter, + RequiredRouteParameter +] : RequiredRouteParameter[]; +declare type RouteHelperOptions = RouteOptions & Optional>; +declare type RouteHelper = ((...args: [...RequiredParameters, RouteHelperOptions]) => string) & RouteHelperExtras; +declare type RouteHelpers = Record; +declare type Configuration = { + prefix: string; + default_url_options: RouteParameters; + special_options_key: string; + serializer: Serializer; +}; +interface RouterExposedMethods { + config(): Configuration; + configure(arg: Partial): Configuration; + serialize: Serializer; +} +declare type KeywordUrlOptions = Optional<{ + host: string; + protocol: string; + subdomain: string; + port: string | number; + anchor: string; + trailing_slash: boolean; + params: RouteParameters; +}>; +declare type RouteOptions = KeywordUrlOptions & RouteParameters; +declare type PartsTable = Record; +declare type ModuleType = "CJS" | "AMD" | "UMD" | "ESM" | "DTS" | "NIL"; +declare const RubyVariables: { + PREFIX: string; + DEPRECATED_GLOBBING_BEHAVIOR: boolean; + SPECIAL_OPTIONS_KEY: string; + DEFAULT_URL_OPTIONS: RouteParameters; + SERIALIZER: Serializer; + ROUTES_OBJECT: RouteHelpers; + MODULE_TYPE: ModuleType; + WRAPPER: (callback: T) => T; +}; +declare const define: undefined | (((arg: unknown[], callback: () => unknown) => void) & { + amd?: unknown; +}); +declare const module: { + exports: any; +} | undefined; +export const configure: RouterExposedMethods['configure']; + +export const config: RouterExposedMethods['config']; + +export const serialize: RouterExposedMethods['serialize']; + +/** + * Generates rails route to + * /about(.:format) + * @param {object | undefined} options + * @returns {string} route path + */ +export const about: (( + options?: {format?: OptionalRouteParameter} & RouteOptions +) => string) & RouteHelperExtras; + +/** + * Generates rails route to + * / + * @param {object | undefined} options + * @returns {string} route path + */ +export const clicks: (( + options?: {} & RouteOptions +) => string) & RouteHelperExtras; + +/** + * Generates rails route to + * / + * @param {object | undefined} options + * @returns {string} route path + */ +export const root: (( + options?: {} & RouteOptions +) => string) & RouteHelperExtras; + +// By some reason this line prevents all types in a file +// from being automatically exported +export {}; diff --git a/app/javascript/routes.js b/app/javascript/routes.js new file mode 100644 index 00000000..7f6e0139 --- /dev/null +++ b/app/javascript/routes.js @@ -0,0 +1,530 @@ +/** + * File generated by js-routes 2.2.4 + * Based on Rails 7.0.3 routes of Templatus::Application + */ +const __jsr = (() => { + const hasProp = (value, key) => Object.prototype.hasOwnProperty.call(value, key); + let NodeTypes; + (function (NodeTypes) { + NodeTypes[NodeTypes["GROUP"] = 1] = "GROUP"; + NodeTypes[NodeTypes["CAT"] = 2] = "CAT"; + NodeTypes[NodeTypes["SYMBOL"] = 3] = "SYMBOL"; + NodeTypes[NodeTypes["OR"] = 4] = "OR"; + NodeTypes[NodeTypes["STAR"] = 5] = "STAR"; + NodeTypes[NodeTypes["LITERAL"] = 6] = "LITERAL"; + NodeTypes[NodeTypes["SLASH"] = 7] = "SLASH"; + NodeTypes[NodeTypes["DOT"] = 8] = "DOT"; + })(NodeTypes || (NodeTypes = {})); + const isBrowser = typeof window !== "undefined"; + const ModuleReferences = { + CJS: { + define(routes) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + module.exports = routes; + }, + isSupported() { + return typeof module === "object"; + }, + }, + AMD: { + define(routes) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + define([], function () { + return routes; + }); + }, + isSupported() { + return typeof define === "function" && !!define.amd; + }, + }, + UMD: { + define(routes) { + if (ModuleReferences.AMD.isSupported()) { + ModuleReferences.AMD.define(routes); + } + else { + if (ModuleReferences.CJS.isSupported()) { + try { + ModuleReferences.CJS.define(routes); + } + catch (error) { + if (error.name !== "TypeError") + throw error; + } + } + } + }, + isSupported() { + return (ModuleReferences.AMD.isSupported() || + ModuleReferences.CJS.isSupported()); + }, + }, + ESM: { + define() { + // Module can only be defined using ruby code generation + }, + isSupported() { + // Its impossible to check if "export" keyword is supported + return true; + }, + }, + NIL: { + define() { + // Defined using const __jsr = + }, + isSupported() { + return true; + }, + }, + DTS: { + // Acts the same as ESM + define(routes) { + ModuleReferences.ESM.define(routes); + }, + isSupported() { + return ModuleReferences.ESM.isSupported(); + }, + }, + }; + class ParametersMissing extends Error { + constructor(...keys) { + super(`Route missing required keys: ${keys.join(", ")}`); + this.keys = keys; + Object.setPrototypeOf(this, Object.getPrototypeOf(this)); + this.name = ParametersMissing.name; + } + } + const UriEncoderSegmentRegex = /[^a-zA-Z0-9\-._~!$&'()*+,;=:@]/g; + const ReservedOptions = [ + "anchor", + "trailing_slash", + "subdomain", + "host", + "port", + "protocol", + ]; + class UtilsClass { + constructor() { + this.configuration = { + prefix: "", + default_url_options: {}, + special_options_key: "_options", + serializer: null || this.default_serializer.bind(this), + }; + } + default_serializer(value, prefix) { + if (this.is_nullable(value)) { + return ""; + } + if (!prefix && !this.is_object(value)) { + throw new Error("Url parameters should be a javascript hash"); + } + prefix = prefix || ""; + const result = []; + if (this.is_array(value)) { + for (const element of value) { + result.push(this.default_serializer(element, prefix + "[]")); + } + } + else if (this.is_object(value)) { + for (let key in value) { + if (!hasProp(value, key)) + continue; + let prop = value[key]; + if (this.is_nullable(prop) && prefix) { + prop = ""; + } + if (this.is_not_nullable(prop)) { + if (prefix) { + key = prefix + "[" + key + "]"; + } + result.push(this.default_serializer(prop, key)); + } + } + } + else { + if (this.is_not_nullable(value)) { + result.push(encodeURIComponent(prefix) + "=" + encodeURIComponent("" + value)); + } + } + return result.join("&"); + } + serialize(object) { + return this.configuration.serializer(object); + } + extract_options(number_of_params, args) { + const last_el = args[args.length - 1]; + if ((args.length > number_of_params && last_el === 0) || + (this.is_object(last_el) && + !this.looks_like_serialized_model(last_el))) { + if (this.is_object(last_el)) { + delete last_el[this.configuration.special_options_key]; + } + return { + args: args.slice(0, args.length - 1), + options: last_el, + }; + } + else { + return { args, options: {} }; + } + } + looks_like_serialized_model(object) { + return (this.is_object(object) && + !(this.configuration.special_options_key in object) && + ("id" in object || "to_param" in object || "toParam" in object)); + } + path_identifier(object) { + const result = this.unwrap_path_identifier(object); + return this.is_nullable(result) || result === false ? "" : "" + result; + } + unwrap_path_identifier(object) { + let result = object; + if (!this.is_object(object)) { + return object; + } + if ("to_param" in object) { + result = object.to_param; + } + else if ("toParam" in object) { + result = object.toParam; + } + else if ("id" in object) { + result = object.id; + } + else { + result = object; + } + return this.is_callable(result) ? result.call(object) : result; + } + partition_parameters(parts, required_params, default_options, call_arguments) { + // eslint-disable-next-line prefer-const + let { args, options } = this.extract_options(parts.length, call_arguments); + if (args.length > parts.length) { + throw new Error("Too many parameters provided for path"); + } + let use_all_parts = args.length > required_params.length; + const parts_options = { + ...this.configuration.default_url_options, + }; + for (const key in options) { + const value = options[key]; + if (!hasProp(options, key)) + continue; + use_all_parts = true; + if (parts.includes(key)) { + parts_options[key] = value; + } + } + options = { + ...this.configuration.default_url_options, + ...default_options, + ...options, + }; + const keyword_parameters = {}; + let query_parameters = {}; + for (const key in options) { + if (!hasProp(options, key)) + continue; + const value = options[key]; + if (key === "params") { + if (this.is_object(value)) { + query_parameters = { + ...query_parameters, + ...value, + }; + } + else { + throw new Error("params value should always be an object"); + } + } + else if (this.is_reserved_option(key)) { + keyword_parameters[key] = value; + } + else { + if (!this.is_nullable(value) && + (value !== default_options[key] || required_params.includes(key))) { + query_parameters[key] = value; + } + } + } + const route_parts = use_all_parts ? parts : required_params; + let i = 0; + for (const part of route_parts) { + if (i < args.length) { + const value = args[i]; + if (!hasProp(parts_options, part)) { + query_parameters[part] = value; + ++i; + } + } + } + return { keyword_parameters, query_parameters }; + } + build_route(parts, required_params, default_options, route, absolute, args) { + const { keyword_parameters, query_parameters, } = this.partition_parameters(parts, required_params, default_options, args); + const missing_params = required_params.filter((param) => !hasProp(query_parameters, param) || + this.is_nullable(query_parameters[param])); + if (missing_params.length) { + throw new ParametersMissing(...missing_params); + } + let result = this.get_prefix() + this.visit(route, query_parameters); + if (keyword_parameters.trailing_slash) { + result = result.replace(/(.*?)[/]?$/, "$1/"); + } + const url_params = this.serialize(query_parameters); + if (url_params.length) { + result += "?" + url_params; + } + result += keyword_parameters.anchor + ? "#" + keyword_parameters.anchor + : ""; + if (absolute) { + result = this.route_url(keyword_parameters) + result; + } + return result; + } + visit(route, parameters, optional = false) { + switch (route[0]) { + case NodeTypes.GROUP: + return this.visit(route[1], parameters, true); + case NodeTypes.CAT: + return this.visit_cat(route, parameters, optional); + case NodeTypes.SYMBOL: + return this.visit_symbol(route, parameters, optional); + case NodeTypes.STAR: + return this.visit_globbing(route[1], parameters, true); + case NodeTypes.LITERAL: + case NodeTypes.SLASH: + case NodeTypes.DOT: + return route[1]; + default: + throw new Error("Unknown Rails node type"); + } + } + is_not_nullable(object) { + return !this.is_nullable(object); + } + is_nullable(object) { + return object === undefined || object === null; + } + visit_cat( + // eslint-disable-next-line @typescript-eslint/no-unused-vars + [_type, left, right], parameters, optional) { + const left_part = this.visit(left, parameters, optional); + let right_part = this.visit(right, parameters, optional); + if (optional && + ((this.is_optional_node(left[0]) && !left_part) || + (this.is_optional_node(right[0]) && !right_part))) { + return ""; + } + // if left_part ends on '/' and right_part starts on '/' + if (left_part[left_part.length - 1] === "/" && right_part[0] === "/") { + // strip slash from right_part + // to prevent double slash + right_part = right_part.substring(1); + } + return left_part + right_part; + } + visit_symbol( + // eslint-disable-next-line @typescript-eslint/no-unused-vars + [_type, key], parameters, optional) { + const value = this.path_identifier(parameters[key]); + delete parameters[key]; + if (value.length) { + return this.encode_segment(value); + } + if (optional) { + return ""; + } + else { + throw new ParametersMissing(key); + } + } + encode_segment(segment) { + return segment.replace(UriEncoderSegmentRegex, (str) => encodeURIComponent(str)); + } + is_optional_node(node) { + return [NodeTypes.STAR, NodeTypes.SYMBOL, NodeTypes.CAT].includes(node); + } + build_path_spec(route, wildcard = false) { + let key; + switch (route[0]) { + case NodeTypes.GROUP: + return "(" + this.build_path_spec(route[1]) + ")"; + case NodeTypes.CAT: + return (this.build_path_spec(route[1]) + this.build_path_spec(route[2])); + case NodeTypes.STAR: + return this.build_path_spec(route[1], true); + case NodeTypes.SYMBOL: + key = route[1]; + if (wildcard) { + return (key.startsWith("*") ? "" : "*") + key; + } + else { + return ":" + key; + } + break; + case NodeTypes.SLASH: + case NodeTypes.DOT: + case NodeTypes.LITERAL: + return route[1]; + default: + throw new Error("Unknown Rails node type"); + } + } + visit_globbing(route, parameters, optional) { + const key = route[1]; + let value = parameters[key]; + delete parameters[key]; + if (this.is_nullable(value)) { + return this.visit(route, parameters, optional); + } + if (this.is_array(value)) { + value = value.join("/"); + } + const result = this.path_identifier(value); + return false + ? result + : encodeURI(result); + } + get_prefix() { + const prefix = this.configuration.prefix; + return prefix.match("/$") + ? prefix.substring(0, prefix.length - 1) + : prefix; + } + route(parts_table, route_spec, absolute = false) { + const required_params = []; + const parts = []; + const default_options = {}; + for (const [part, { r: required, d: value }] of Object.entries(parts_table)) { + parts.push(part); + if (required) { + required_params.push(part); + } + if (this.is_not_nullable(value)) { + default_options[part] = value; + } + } + const result = (...args) => { + return this.build_route(parts, required_params, default_options, route_spec, absolute, args); + }; + result.requiredParams = () => required_params; + result.toString = () => { + return this.build_path_spec(route_spec); + }; + return result; + } + route_url(route_defaults) { + const hostname = route_defaults.host || this.current_host(); + if (!hostname) { + return ""; + } + const subdomain = route_defaults.subdomain + ? route_defaults.subdomain + "." + : ""; + const protocol = route_defaults.protocol || this.current_protocol(); + let port = route_defaults.port || + (!route_defaults.host ? this.current_port() : undefined); + port = port ? ":" + port : ""; + return protocol + "://" + subdomain + hostname + port; + } + current_host() { + var _a; + return (isBrowser && ((_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.hostname)) || ""; + } + current_protocol() { + var _a, _b; + return ((isBrowser && ((_b = (_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.protocol) === null || _b === void 0 ? void 0 : _b.replace(/:$/, ""))) || "http"); + } + current_port() { + var _a; + return (isBrowser && ((_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.port)) || ""; + } + is_object(value) { + return (typeof value === "object" && + Object.prototype.toString.call(value) === "[object Object]"); + } + is_array(object) { + return object instanceof Array; + } + is_callable(object) { + return typeof object === "function" && !!object.call; + } + is_reserved_option(key) { + return ReservedOptions.includes(key); + } + configure(new_config) { + this.configuration = { ...this.configuration, ...new_config }; + return this.configuration; + } + config() { + return { ...this.configuration }; + } + is_module_supported(name) { + return ModuleReferences[name].isSupported(); + } + ensure_module_supported(name) { + if (!this.is_module_supported(name)) { + throw new Error(`${name} is not supported by runtime`); + } + } + define_module(name, module) { + this.ensure_module_supported(name); + ModuleReferences[name].define(module); + } + } + const Utils = new UtilsClass(); + // We want this helper name to be short + const __jsr = { + r(parts_table, route_spec, absolute) { + return Utils.route(parts_table, route_spec, absolute); + }, + }; + const result = { + ...__jsr, + configure: (config) => { + return Utils.configure(config); + }, + config: () => { + return Utils.config(); + }, + serialize: (object) => { + return Utils.serialize(object); + }, + ...{}, + }; + Utils.define_module("ESM", result); + return result; +})(); +export const configure = __jsr.configure; + +export const config = __jsr.config; + +export const serialize = __jsr.serialize; + +/** + * Generates rails route to + * /about(.:format) + * @param {object | undefined} options + * @returns {string} route path + */ +export const about = __jsr.r({"format":{}}, [2,[7,"/"],[2,[6,"about"],[1,[2,[8,"."],[3,"format"]]]]]); + +/** + * Generates rails route to + * / + * @param {object | undefined} options + * @returns {string} route path + */ +export const clicks = __jsr.r({}, [7,"/"]); + +/** + * Generates rails route to + * / + * @param {object | undefined} options + * @returns {string} route path + */ +export const root = __jsr.r({}, [7,"/"]); + diff --git a/app/javascript/src/App.vue b/app/javascript/src/App.vue deleted file mode 100644 index c04a2d5b..00000000 --- a/app/javascript/src/App.vue +++ /dev/null @@ -1,25 +0,0 @@ - - - diff --git a/app/javascript/src/components/AppBackground.vue b/app/javascript/src/components/AppBackground.vue deleted file mode 100644 index 030a2538..00000000 --- a/app/javascript/src/components/AppBackground.vue +++ /dev/null @@ -1,35 +0,0 @@ - diff --git a/app/javascript/src/components/AppFooter.vue b/app/javascript/src/components/AppFooter.vue deleted file mode 100644 index 0a64e768..00000000 --- a/app/javascript/src/components/AppFooter.vue +++ /dev/null @@ -1,68 +0,0 @@ - - - diff --git a/app/javascript/src/components/AppHeader.vue b/app/javascript/src/components/AppHeader.vue deleted file mode 100644 index 8654c417..00000000 --- a/app/javascript/src/components/AppHeader.vue +++ /dev/null @@ -1,44 +0,0 @@ - - - diff --git a/app/javascript/src/components/ClickButton.vue b/app/javascript/src/components/ClickButton.vue deleted file mode 100644 index 9987408f..00000000 --- a/app/javascript/src/components/ClickButton.vue +++ /dev/null @@ -1,53 +0,0 @@ - - - diff --git a/app/javascript/src/components/ClickList.vue b/app/javascript/src/components/ClickList.vue deleted file mode 100644 index f3a19c43..00000000 --- a/app/javascript/src/components/ClickList.vue +++ /dev/null @@ -1,51 +0,0 @@ - - - diff --git a/app/javascript/src/components/GitVersion.vue b/app/javascript/src/components/GitVersion.vue deleted file mode 100644 index b25d0f72..00000000 --- a/app/javascript/src/components/GitVersion.vue +++ /dev/null @@ -1,33 +0,0 @@ - - - diff --git a/app/javascript/src/components/LoadingAnimation.vue b/app/javascript/src/components/LoadingAnimation.vue deleted file mode 100644 index e288e2d8..00000000 --- a/app/javascript/src/components/LoadingAnimation.vue +++ /dev/null @@ -1,17 +0,0 @@ - diff --git a/app/javascript/src/components/PageTitle.vue b/app/javascript/src/components/PageTitle.vue deleted file mode 100644 index 2bcaa17b..00000000 --- a/app/javascript/src/components/PageTitle.vue +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/app/javascript/src/pages/AboutPage.vue b/app/javascript/src/pages/AboutPage.vue deleted file mode 100644 index faf22904..00000000 --- a/app/javascript/src/pages/AboutPage.vue +++ /dev/null @@ -1,244 +0,0 @@ - - - diff --git a/app/javascript/src/pages/HomePage.vue b/app/javascript/src/pages/HomePage.vue deleted file mode 100644 index 472a5491..00000000 --- a/app/javascript/src/pages/HomePage.vue +++ /dev/null @@ -1,51 +0,0 @@ - - - diff --git a/app/javascript/src/pages/NotFound.vue b/app/javascript/src/pages/NotFound.vue deleted file mode 100644 index e537f31e..00000000 --- a/app/javascript/src/pages/NotFound.vue +++ /dev/null @@ -1,11 +0,0 @@ - - - diff --git a/app/javascript/src/plugins/plausible.js b/app/javascript/src/plugins/plausible.js deleted file mode 100644 index 31c4b1b5..00000000 --- a/app/javascript/src/plugins/plausible.js +++ /dev/null @@ -1,13 +0,0 @@ -import Plausible from 'plausible-tracker'; - -export default { - install: (app, options) => { - const { enableAutoPageviews, enableAutoOutboundTracking } = - Plausible(options); - - enableAutoPageviews(); - enableAutoOutboundTracking(); - - app.provide('plausible'); - }, -}; diff --git a/app/javascript/src/router.ts b/app/javascript/src/router.ts deleted file mode 100644 index 878a94e4..00000000 --- a/app/javascript/src/router.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { createWebHashHistory, createRouter, RouteRecordRaw } from 'vue-router'; -import HomePage from '@/pages/HomePage.vue'; -import AboutPage from '@/pages/AboutPage.vue'; -import NotFound from '@/pages/NotFound.vue'; - -const routes: Array = [ - { - path: '/', - name: 'Home', - component: HomePage, - props: { - name: 'Templatus', - }, - }, - { - path: '/about', - name: 'About', - component: AboutPage, - }, - { path: '/:pathMatch(.*)', component: NotFound }, -]; - -const router = createRouter({ - history: createWebHashHistory(), - routes, -}); - -export default router; diff --git a/app/javascript/src/shims-vue.d.ts b/app/javascript/src/shims-vue.d.ts deleted file mode 100644 index 64388a32..00000000 --- a/app/javascript/src/shims-vue.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -declare module '*.vue' { - import { defineComponent } from 'vue'; - const Component: ReturnType; - export default Component; -} - -declare module '@rails/request.js'; -declare module '@/plugins/plausible'; - -declare module '*.svg' { - export default '' as string; -} diff --git a/app/javascript/src/stores/click.ts b/app/javascript/src/stores/click.ts deleted file mode 100644 index cfc24b97..00000000 --- a/app/javascript/src/stores/click.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { defineStore } from 'pinia'; -import { createConsumer, Subscription } from '@rails/actioncable'; -import { get, post } from '@rails/request.js'; - -export type Click = { - id: number; - created_at: string; - ip: string; - user_agent: string; -}; - -let channel: Subscription | null = null; - -export const useClickStore = defineStore('click', { - state: () => ({ - loaded: false, - subscribed: false, - total: 0, - items: [] as Click[], - }), - - actions: { - sendClick() { - post('/clicks'); - }, - - async getClicks() { - const response = await get('/clicks', { - responseKind: 'json', - }); - const json = await response.json; - - this.total = json.total; - this.items = json.items; - this.loaded = true; - }, - - subscribe() { - channel = createConsumer().subscriptions.create( - { - channel: 'ClicksChannel', - }, - { - received: (click: Click) => { - this.total += 1; - this.items.unshift(click); - }, - }, - ); - this.subscribed = true; - }, - - unsubscribe() { - if (channel) { - channel.unsubscribe(); - channel.consumer.disconnect(); - } - this.subscribed = false; - }, - }, -}); diff --git a/app/javascript/src/use/online-offline.ts b/app/javascript/src/use/online-offline.ts deleted file mode 100644 index a86d5728..00000000 --- a/app/javascript/src/use/online-offline.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Ref, ref, onMounted, onUnmounted } from 'vue'; - -export default function useOnlineOffline(): { online: Ref } { - const online = ref(navigator.onLine); - - function setOnline() { - online.value = true; - } - - function setOffline() { - online.value = false; - } - - onMounted(() => { - window.addEventListener('online', setOnline); - window.addEventListener('offline', setOffline); - }); - - onUnmounted(() => { - window.removeEventListener('online', setOnline); - window.removeEventListener('offline', setOffline); - }); - - return { - online, - }; -} diff --git a/app/javascript/stores/clicks.ts b/app/javascript/stores/clicks.ts new file mode 100644 index 00000000..2e932fd3 --- /dev/null +++ b/app/javascript/stores/clicks.ts @@ -0,0 +1,46 @@ +import { writable } from 'svelte/store'; +import { createConsumer } from '@rails/actioncable'; +import { Inertia } from '@inertiajs/inertia'; +import * as Routes from '@/routes'; + +import type { Subscription } from 'rails__actioncable'; + +let subscription: Subscription; + +export type Click = { + id: number; + created_at: string; + ip: string; + user_agent: string; +}; + +export const currentItems = writable([] as Click[]); +export const currentTotal = writable(0); +export const subscribed = writable(false); + +export function sendClick(): void { + Inertia.post(Routes.clicks()); +} + +export function startCable(): void { + subscription = createConsumer().subscriptions.create( + { + channel: 'ClicksChannel', + }, + { + received: (click: Click) => { + currentTotal.update((n) => n + 1); + currentItems.update((items) => [click, ...items]); + }, + }, + ); + subscribed.set(true); +} + +export function stopCable(): void { + if (subscription) { + subscription.unsubscribe(); + subscription.consumer.disconnect(); + } + subscribed.set(false); +} diff --git a/app/javascript/src/utils/metaContent.ts b/app/javascript/utils/metaContent.ts similarity index 100% rename from app/javascript/src/utils/metaContent.ts rename to app/javascript/utils/metaContent.ts diff --git a/app/javascript/utils/setupHoneybadger.ts b/app/javascript/utils/setupHoneybadger.ts new file mode 100644 index 00000000..784488ed --- /dev/null +++ b/app/javascript/utils/setupHoneybadger.ts @@ -0,0 +1,13 @@ +import Honeybadger from '@honeybadger-io/js'; +import { metaContent } from './metaContent'; + +const honeybadgerApiKey = metaContent('honeybadger-api-key'); +if (honeybadgerApiKey) { + const gitCommitVersion = metaContent('git-commit-version'); + + Honeybadger.configure({ + apiKey: honeybadgerApiKey, + environment: 'production', + revision: gitCommitVersion, + }); +} diff --git a/app/javascript/utils/setupInertia.ts b/app/javascript/utils/setupInertia.ts new file mode 100644 index 00000000..b71c8d2c --- /dev/null +++ b/app/javascript/utils/setupInertia.ts @@ -0,0 +1,21 @@ +import axios from 'axios'; +import { createInertiaApp } from '@inertiajs/inertia-svelte'; +import { InertiaProgress } from '@inertiajs/progress'; +import { metaContent } from '@/utils/metaContent'; + +const pages = import.meta.globEager('../pages/**/*.svelte'); + +axios.defaults.headers.common['X-CSRF-Token'] = metaContent('csrf-token'); + +InertiaProgress.init({ + showSpinner: true, +}); + +createInertiaApp({ + resolve: (name: string) => pages[`../pages/${name}.svelte`], + + setup({ el, App, props }) { + // eslint-disable-next-line no-new + new App({ target: el, props }); + }, +}); diff --git a/app/javascript/utils/setupPlausible.ts b/app/javascript/utils/setupPlausible.ts new file mode 100644 index 00000000..27f9feee --- /dev/null +++ b/app/javascript/utils/setupPlausible.ts @@ -0,0 +1,17 @@ +import { metaContent } from '@/utils/metaContent'; +import { Inertia } from '@inertiajs/inertia'; +import Plausible from 'plausible-tracker'; + +const plausibleUrl = metaContent('plausible-url'); +if (plausibleUrl) { + const plausible = Plausible({ + domain: metaContent('app-host'), + apiHost: plausibleUrl, + }); + + plausible.enableAutoOutboundTracking(); + + Inertia.on('navigate', () => { + plausible.trackPageview(); + }); +} diff --git a/app/models/click.rb b/app/models/click.rb index 273ab221..19c253e8 100644 --- a/app/models/click.rb +++ b/app/models/click.rb @@ -1,9 +1,4 @@ class Click < ApplicationRecord validates :ip, presence: true validates :user_agent, presence: true - - # There is no `updated_at` in the database - def updated_at - created_at - end end diff --git a/app/services/features.rb b/app/services/features.rb new file mode 100644 index 00000000..e10fa2d8 --- /dev/null +++ b/app/services/features.rb @@ -0,0 +1,45 @@ +class Features + def data + file = File.read("#{__dir__}/features/data.json") + json = JSON.parse(file) + + json.each do |group| + # Replace `version` placeholders (containing the method name) with the actual version + group['items'].each do |item| + item['version'] = __send__(item['version']) if item.key?('version') + end + end + end + + private + + def alpine_version + return unless RUBY_PLATFORM.include?('linux') + + `cat /etc/alpine-release 2>/dev/null`.chomp + end + + def ruby_version + RUBY_VERSION + end + + def rails_version + Rails.version + end + + def puma_version + Puma::Const::PUMA_VERSION + end + + def postgresql_version + ActiveRecord::Base.connection.select_value('SHOW server_version;') + end + + def redis_version + Redis.new.info['redis_version'] + end + + def sidekiq_version + Sidekiq::VERSION + end +end diff --git a/app/services/features/data.json b/app/services/features/data.json new file mode 100644 index 00000000..17be9951 --- /dev/null +++ b/app/services/features/data.json @@ -0,0 +1,128 @@ +[ + { + "name": "The backend", + "slogan": "Server side", + "items": [ + { + "name": "Ruby", + "version": "ruby_version", + "href": "https://www.ruby-lang.org/", + "description": "A dynamic, open source programming language with a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write." + }, + { + "name": "Ruby on Rails", + "version": "rails_version", + "href": "https://rubyonrails.org/", + "description": "Rails is a web application development framework written in the Ruby programming language. It is designed to make programming web applications easier by making assumptions about what every developer needs to get started." + }, + { + "name": "PostgreSQL", + "version": "postgresql_version", + "href": "https://www.postgresql.org/", + "description": "PostgreSQL is a powerful, open source object-relational database system with over 30 years of active development that has earned it a strong reputation for reliability, feature robustness, and performance." + }, + { + "name": "Puma", + "version": "puma_version", + "href": "https://puma.io/", + "description": "Puma is a simple, fast, multi-threaded, and highly concurrent HTTP 1.1 server for Ruby/Rack applications." + }, + { + "name": "Redis", + "version": "redis_version", + "href": "https://redis.io/", + "description": "Redis is an open source, in-memory data structure store, used as a database, cache, and message broker." + }, + { + "name": "Sidekiq", + "version": "sidekiq_version", + "href": "https://sidekiq.org/", + "description": "Simple, efficient background processing for Ruby

Admin frontend

" + } + ] + }, + { + "name": "The frontend", + "slogan": "Client side", + "items": [ + { + "name": "Inertia.js", + "href": "https://inertiajs.com/", + "description": "Build single-page apps, without building an API. Inertia.js lets you quickly build modern single-page React, Vue and Svelte apps using classic server-side routing and controllers." + }, + { + "name": "Svelte", + "href": "https://svelte.dev/", + "description": "Svelte is a radical new approach to building user interfaces. Whereas traditional frameworks like React and Vue do the bulk of their work in the browser, Svelte shifts that work into a compile step that happens when you build your app." + }, + { + "name": "Tailwind CSS 3", + "href": "https://tailwindcss.com/", + "description": "A utility-first CSS framework packed with classes that can be composed to build any design, directly in your markup." + }, + { + "name": "Tabler Icons", + "href": "https://tablericons.com/", + "description": "1424 Open source free SVG icons. Highly customizable. No attribution required. For commercial use." + }, + { + "name": "Vite", + "href": "https://vitejs.dev/", + "description": "Next generation frontend tooling. It's fast!" + } + ] + }, + { + "name": "Continuous integration", + "slogan": "Quality insurance", + "items": [ + { + "name": "GitHub Actions", + "href": "https://github.com/features/actions", + "description": "Test, build and deliver on every push to GitHub" + }, + { + "name": "RSpec", + "href": "https://rspec.info/", + "description": "Behaviour Driven Development for Ruby. Making TDD Productive and Fun." + }, + { + "name": "RuboCop", + "href": "https://rubocop.org/", + "description": "The Ruby Linter/Formatter that Serves and Protects" + }, + { + "name": "ESLint", + "href": "https://eslint.org/", + "description": "ESLint statically analyzes your code to quickly find problems" + }, + { + "name": "Cypress", + "href": "https://cypress.io/", + "description": "Fast, easy and reliable testing for anything that runs in a browser." + } + ] + }, + { + "name": "Deployment", + "slogan": "Ship it!", + "items": [ + { + "name": "Alpine Linux", + "version": "alpine_version", + "href": "https://alpinelinux.org/", + "description": "Alpine Linux is an independent, non-commercial, general purpose Linux distribution designed for power users who appreciate security, simplicity and resource efficiency." + }, + { + "name": "Docker", + "href": "https://www.docker.com/", + "description": "Dockerized using an optimized base image." + }, + { + "name": "Plausible", + "href": "https://plausible.io/", + "description": "Plausible is lightweight and open source web analytics. No cookies and fully compliant with GDPR, CCPA and PECR." + } + ] + } +] diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index a55fb9df..a2c8ff46 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -3,16 +3,16 @@ - Templatus + Templatus-Inertia - + - + - + @@ -32,12 +32,6 @@ <% end %> - <% cache Rails.configuration.x.git.commit_version do %> - <% versions.each do |name, version| %> - <%= tag.meta name: "version-#{name}", content: version %> - <% end %> - <% end %> - <%= csrf_meta_tags %> <%= action_cable_meta_tag %> diff --git a/app/views/statics/manifest.webmanifest.erb b/app/views/statics/manifest.webmanifest.erb index 6784b53d..fca874b0 100644 --- a/app/views/statics/manifest.webmanifest.erb +++ b/app/views/statics/manifest.webmanifest.erb @@ -1,6 +1,6 @@ { - "name": "Templatus (Vue edition)", - "short_name": "Templatus", + "name": "Templatus (Inertia edition)", + "short_name": "Templatus-I", "start_url": "/", "display": "standalone", "orientation": "portrait", diff --git a/app/views/vue/index.html.erb b/app/views/vue/index.html.erb deleted file mode 100644 index 55efda8e..00000000 --- a/app/views/vue/index.html.erb +++ /dev/null @@ -1 +0,0 @@ -
diff --git a/config/application.rb b/config/application.rb index b2124f4b..e8fb1a9f 100644 --- a/config/application.rb +++ b/config/application.rb @@ -30,9 +30,13 @@ class Application < Rails::Application # config.time_zone = "Central Time (US & Canada)" # config.eager_load_paths << Rails.root.join("extras") + config.exceptions_app = ->(env) do + ExceptionsController.action(:show).call(env) + end + config.time_zone = ENV.fetch('TIME_ZONE', 'Berlin') - config.x.app_host = ENV.fetch('APP_HOST', 'templatus.test') + config.x.app_host = ENV.fetch('APP_HOST', 'templatus-inertia.test') config.x.git.commit_version = ENV.fetch('COMMIT_VERSION') { `git describe --always`.chomp } diff --git a/config/database.yml b/config/database.yml index 47e00028..a760ada1 100644 --- a/config/database.yml +++ b/config/database.yml @@ -51,14 +51,14 @@ default: &default development: <<: *default # Use test database in Cypress mode. This allows writing Cypress tests without having to restart the server - database: "<%= Rails.configuration.x.cypress ? 'templatus_test' : 'templatus_development' %>" + database: "<%= Rails.configuration.x.cypress ? 'templatus-inertia_test' : 'templatus-inertia_development' %>" # Warning: The database defined as "test" will be erased and # re-generated from your development database when you run "rake". # Do not set this db to the same as development or production. test: <<: *default - database: templatus_test + database: templatus-inertia_test # As with config/credentials.yml, you never want to store sensitive information, # like your database password, in your source code. If your source code is @@ -82,4 +82,4 @@ test: # production: <<: *default - database: templatus_production + database: templatus-inertia_production diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb index 42b00daf..f630f95e 100644 --- a/config/initializers/content_security_policy.rb +++ b/config/initializers/content_security_policy.rb @@ -32,7 +32,14 @@ *[:self, Rails.configuration.asset_host.presence].compact, ) policy.style_src( - *[:self, Rails.configuration.asset_host.presence].compact, + *[ + :self, + Rails.configuration.asset_host.presence, + # Allow @inertiajs/progress to display progress bar + "'sha256-kCeyw5rRT2DINADvWYmAhXLhQs4dKZrnn2sofIDmprs='", + # Allow Sevelte to display animations, see https://github.com/sveltejs/svelte/issues/6662#issuecomment-917492365 + "'sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU='", + ].compact, ) policy.frame_src( *[:self, Rails.configuration.asset_host.presence].compact, diff --git a/config/initializers/inertia_rails.rb b/config/initializers/inertia_rails.rb new file mode 100644 index 00000000..86f5e633 --- /dev/null +++ b/config/initializers/inertia_rails.rb @@ -0,0 +1,3 @@ +InertiaRails.configure do |config| + config.version = Rails.configuration.x.git.commit_version +end diff --git a/config/initializers/js_routes.rb b/config/initializers/js_routes.rb new file mode 100644 index 00000000..b71c7312 --- /dev/null +++ b/config/initializers/js_routes.rb @@ -0,0 +1,23 @@ +JsRoutes.setup do |config| + # Setup your JS module system: + # ESM, CJS, AMD, UMD or nil + config.module_type = 'ESM' + + config.exclude = [ + # Default Rails routes not required from Inertia.js + /rails_blob/, + /rails_disk/, + /rails_info/, + /rails_mailers/, + /rails_service/, + /rails_conductor/, + /rails_direct_uploads/, + /rails_.+_inbound/, + # Sidekiq admin UI + /sidekiq/, + # Other + /webmanifest/, + ] + + config.compact = true +end diff --git a/config/routes.rb b/config/routes.rb index 2af04000..513a505a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -11,9 +11,10 @@ end end - resources :clicks, only: %i[index create] + resources :clicks, only: %i[index create], path: '/' + resource :about, controller: 'about', only: %i[show] get '/manifest.v1.webmanifest', to: 'statics#manifest', as: :webmanifest - root to: 'vue#index' + root to: 'clicks#index' end diff --git a/config/vite.json b/config/vite.json index 7539d8eb..31fbbb51 100644 --- a/config/vite.json +++ b/config/vite.json @@ -6,7 +6,7 @@ "development": { "autoBuild": true, "publicOutputDir": "vite-dev", - "host": "vite.templatus.test", + "host": "vite.templatus-inertia.test", "port": 3036 }, "test": { diff --git a/cypress.config.ts b/cypress.config.ts index deface80..5747ec3c 100644 --- a/cypress.config.ts +++ b/cypress.config.ts @@ -1,7 +1,7 @@ import { defineConfig } from 'cypress'; export default defineConfig({ - projectId: '5d6bqs', + projectId: '6g6s4z', screenshotsFolder: 'tmp/cypress_screenshots', trashAssetsBeforeRuns: false, videosFolder: 'tmp/cypress_videos', @@ -13,7 +13,7 @@ export default defineConfig({ setupNodeEvents(on, config) { return require('./spec/cypress/plugins/index.js')(on, config); }, - baseUrl: 'https://templatus.test', + baseUrl: 'https://templatus-inertia.test', specPattern: 'spec/cypress/integration/**/*.{js,jsx,ts,tsx}', supportFile: 'spec/cypress/support/index.js', }, diff --git a/docs/network.png b/docs/network.png index 084a692b..0d6435bf 100644 Binary files a/docs/network.png and b/docs/network.png differ diff --git a/docs/web-page-test.png b/docs/web-page-test.png index a8de6bd0..f9459efd 100644 Binary files a/docs/web-page-test.png and b/docs/web-page-test.png differ diff --git a/jest.config.js b/jest.config.js index 1a66bbd1..25364275 100644 --- a/jest.config.js +++ b/jest.config.js @@ -2,22 +2,28 @@ module.exports = { verbose: true, roots: ['spec/javascript'], moduleNameMapper: { - '^@/(.*)$': '/app/javascript/src/$1', - '^@test/(.*)$': '/spec/javascript/src/$1', + '^@/(.*)$': '/app/javascript/$1', + '^@test/(.*)$': '/spec/javascript/$1', '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': 'jest-transform-stub', }, - moduleFileExtensions: ['js', 'ts', 'json', 'vue'], + moduleFileExtensions: ['js', 'ts', 'svelte'], preset: 'ts-jest', testMatch: ['**/?(*.)+(spec|test).+(ts|tsx)'], transform: { - '^.+\\.tsx?$': 'ts-jest', - '^.+\\.vue$': '@vue/vue3-jest', + '^.+\\.ts$': 'ts-jest', + '^.+\\.svelte$': [ + 'svelte-jester', + { + preprocess: true, + }, + ], + '.+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$': + 'jest-transform-stub', }, testEnvironment: 'jsdom', testEnvironmentOptions: { - url: 'https://templatus.test/', + url: 'https://templatus-inertia.test/', customExportConditions: ['node', 'node-addons'], }, - snapshotSerializers: ['/node_modules/jest-serializer-vue'], }; diff --git a/package.json b/package.json index b00cb128..49ef5e4b 100644 --- a/package.json +++ b/package.json @@ -1,67 +1,69 @@ { "name": "templatus", + "version": "0.1.0", "private": true, "scripts": { - "test": "TZ=UTC jest --coverage", - "lint": "eslint --ext .js,.ts,.vue --cache .", - "tsc": "vue-tsc --noEmit" + "test": "jest --coverage", + "lint": "eslint --ext .js,.ts,.svelte --cache .", + "tsc": "tsc --noEmit" }, "dependencies": { - "@heroicons/vue": "^1.0.6", - "@honeybadger-io/vue": "^3.1.0", + "@honeybadger-io/js": "^4.0.3", + "@inertiajs/inertia": "^0.11.0", + "@inertiajs/inertia-svelte": "^0.8.0", + "@inertiajs/progress": "^0.2.7", "@rails/actioncable": "^7.0.3", - "@rails/request.js": "^0.0.6", - "@tailwindcss/forms": "^0.5.2", - "@types/rails__actioncable": "^6.1.6", - "@vue/compiler-sfc": "^3.2.37", - "autoprefixer": "^10.4.7", - "pinia": "^2.0.14", "plausible-tracker": "^0.3.8", - "postcss": "^8.4.14", - "register-service-worker": "^1.7.2", - "tailwindcss": "^3.0.24", - "timeago.js": "^4.0.2", - "typescript": "^4.7.3", - "vue": "^3.2.37", - "vue-router": "^4.0.15" + "tabler-icons-svelte": "^1.8.0", + "timeago.js": "^4.0.2" }, - "version": "0.1.0", "devDependencies": { - "@babel/core": "^7.18.2", + "@feltcoop/eslint-config": "^0.1.7", "@prettier/plugin-ruby": "^3.1.2", "@size-limit/file": "^7.0.8", + "@sveltejs/vite-plugin-svelte": "^1.0.0-next.48", + "@tailwindcss/forms": "^0.5.2", + "@testing-library/dom": "^8.13.0", + "@testing-library/jest-dom": "^5.16.4", + "@testing-library/svelte": "^3.1.3", + "@testing-library/user-event": "^14.2.0", + "@tsconfig/svelte": "^3.0.0", "@types/jest": "^28.1.1", + "@types/rails__actioncable": "^6.1.6", "@typescript-eslint/eslint-plugin": "^5.27.1", "@typescript-eslint/parser": "^5.27.1", - "@vitejs/plugin-vue": "^2.3.3", - "@vue/test-utils": "2.0.0", - "@vue/vue3-jest": "^28.0.0", - "babel-jest": "^28.1.1", + "acorn": "^8.7.1", + "autoprefixer": "^10.4.7", "cypress": "^10.0.3", "eslint": "^8.17.0", "eslint-config-prettier": "^8.5.0", "eslint-plugin-cypress": "^2.12.1", - "eslint-plugin-jest": "^26.5.3", "eslint-plugin-prettier": "^4.0.0", - "eslint-plugin-vue": "^9.1.0", + "eslint-plugin-svelte3": "^4.0.0", "jest": "^28.1.1", "jest-environment-jsdom": "^28.1.1", - "jest-serializer-vue": "^2.0.2", "jest-transform-stub": "^2.0.0", + "postcss": "^8.4.14", "prettier": "^2.6.2", + "prettier-plugin-svelte": "^2.7.0", "prettier-plugin-tailwindcss": "^0.1.11", "rollup": "^2.75.6", "rollup-plugin-gzip": "^3.0.1", "size-limit": "^7.0.8", + "svelte": "^3.48.0", + "svelte-jester": "^2.3.2", + "svelte-preprocess": "^4.10.7", + "tailwindcss": "^3.0.24", + "test-jest": "^1.0.1", "ts-jest": "^28.0.4", + "typescript": "^4.7.3", "vite": "^2.9.10", "vite-plugin-full-reload": "^1.0.0", - "vite-plugin-ruby": "^3.0.12", - "vue-tsc": "^0.37.3" + "vite-plugin-ruby": "^3.0.12" }, "size-limit": [ { - "limit": "65 kB", + "limit": "75 kB", "path": "public/{vite,vite-dev,vite-test}/assets/*.js" } ] diff --git a/public/404.html b/public/404.html deleted file mode 100644 index 8d884591..00000000 --- a/public/404.html +++ /dev/null @@ -1,69 +0,0 @@ - - - - The page you were looking for doesn't exist (404) - - - - - - -
-
-

The page you were looking for doesn't exist.

-

You may have mistyped the address or the page may have moved.

-
-

- If you are the application owner check the logs for more information. -

-
- - diff --git a/public/422.html b/public/422.html deleted file mode 100644 index 845c5328..00000000 --- a/public/422.html +++ /dev/null @@ -1,69 +0,0 @@ - - - - The change you wanted was rejected (422) - - - - - - -
-
-

The change you wanted was rejected.

-

Maybe you tried to change something you didn't have access to.

-
-

- If you are the application owner check the logs for more information. -

-
- - diff --git a/public/500.html b/public/500.html deleted file mode 100644 index 21fe4eca..00000000 --- a/public/500.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - We're sorry, but something went wrong (500) - - - - - - -
-
-

We're sorry, but something went wrong.

-
-

- If you are the application owner check the logs for more information. -

-
- - diff --git a/public/android-chrome-192x192.png b/public/android-chrome-192x192.png index 0bfb68a3..1499a986 100644 Binary files a/public/android-chrome-192x192.png and b/public/android-chrome-192x192.png differ diff --git a/public/android-chrome-512x512.png b/public/android-chrome-512x512.png index 04cc005d..5dee46c2 100644 Binary files a/public/android-chrome-512x512.png and b/public/android-chrome-512x512.png differ diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png index 48da0d8e..bd485bb7 100644 Binary files a/public/apple-touch-icon.png and b/public/apple-touch-icon.png differ diff --git a/public/favicon-16x16.png b/public/favicon-16x16.png index 33312caf..1c4d541e 100644 Binary files a/public/favicon-16x16.png and b/public/favicon-16x16.png differ diff --git a/public/favicon-32x32.png b/public/favicon-32x32.png index 1cc1543f..2c2a561d 100644 Binary files a/public/favicon-32x32.png and b/public/favicon-32x32.png differ diff --git a/public/favicon.ico b/public/favicon.ico index 4e39c767..d26bb7bb 100644 Binary files a/public/favicon.ico and b/public/favicon.ico differ diff --git a/public/maskable_icon_x384.png b/public/maskable_icon_x384.png index bce715ce..575a2d10 100644 Binary files a/public/maskable_icon_x384.png and b/public/maskable_icon_x384.png differ diff --git a/public/mstile-144x144.png b/public/mstile-144x144.png index d11506b7..27dcb264 100644 Binary files a/public/mstile-144x144.png and b/public/mstile-144x144.png differ diff --git a/public/mstile-150x150.png b/public/mstile-150x150.png index b33e645d..993fdcdb 100644 Binary files a/public/mstile-150x150.png and b/public/mstile-150x150.png differ diff --git a/public/mstile-310x150.png b/public/mstile-310x150.png index 2c4b46cd..1a84e770 100644 Binary files a/public/mstile-310x150.png and b/public/mstile-310x150.png differ diff --git a/public/mstile-310x310.png b/public/mstile-310x310.png index 84aefa29..c3d070f9 100644 Binary files a/public/mstile-310x310.png and b/public/mstile-310x310.png differ diff --git a/public/mstile-70x70.png b/public/mstile-70x70.png index 81be9d26..95c33213 100644 Binary files a/public/mstile-70x70.png and b/public/mstile-70x70.png differ diff --git a/public/safari-pinned-tab.svg b/public/safari-pinned-tab.svg index 8844219e..b6fd20d0 100644 --- a/public/safari-pinned-tab.svg +++ b/public/safari-pinned-tab.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/public/sw.js b/public/sw.js deleted file mode 100644 index 67c65b47..00000000 --- a/public/sw.js +++ /dev/null @@ -1,11 +0,0 @@ -self.addEventListener('install', (_event) => { - // console.log('sw.js: Service worker has been installed.', event); -}); - -self.addEventListener('activate', (_event) => { - // console.log('sw.js: Service worker has been activated.', event); -}); - -self.addEventListener('fetch', (_event) => { - // console.log('sw.js: Service worker is fetching', event); -}); diff --git a/spec/javascript/components/GitVersion.test.ts b/spec/javascript/components/GitVersion.test.ts new file mode 100644 index 00000000..ff01f3c1 --- /dev/null +++ b/spec/javascript/components/GitVersion.test.ts @@ -0,0 +1,21 @@ +import { waitFor, render, screen } from '@testing-library/svelte'; +import '@testing-library/jest-dom'; +import GitVersion from '@/components/GitVersion.svelte'; + +describe('GitVersion', () => { + test('renders version', async () => { + const { getByText } = render(GitVersion, { + target: document.body, + props: { + commitVersion: 'v0.0.1-123-7654321', + commitTime: '2021-06-01T12:00:00+02:00', + }, + }); + + await waitFor(() => + expect(getByText('v0.0.1-123-7654321')).toBeInTheDocument(), + ); + + expect(getByText('v0.0.1-123-7654321')).toBeInTheDocument(); + }); +}); diff --git a/spec/javascript/src/App.test.ts b/spec/javascript/src/App.test.ts deleted file mode 100644 index 5c26505a..00000000 --- a/spec/javascript/src/App.test.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { mount } from '@vue/test-utils'; - -import App from '@/App.vue'; - -import { createRouter, createWebHistory } from 'vue-router'; - -const router = createRouter({ - history: createWebHistory(), - routes: [ - { - path: '/', - component: { template: 'Home page' }, - }, - { - path: '/about', - component: { template: 'About page' }, - }, - ], -}); - -describe('App', () => { - const wrapper = mount(App, { - global: { - plugins: [router], - }, - }); - - afterAll(() => { - wrapper.unmount(); - }); - - test('matches snapshot', () => { - expect(wrapper.html()).toMatchSnapshot(); - }); - - test('recognizes online/offline', async () => { - window.dispatchEvent(new window.Event('offline')); - await wrapper.vm.$nextTick(); - expect(wrapper.html()).toContain('offline'); - - window.dispatchEvent(new window.Event('online')); - await wrapper.vm.$nextTick(); - expect(wrapper.html()).not.toContain('offline'); - }); -}); diff --git a/spec/javascript/src/__snapshots__/App.test.ts.snap b/spec/javascript/src/__snapshots__/App.test.ts.snap deleted file mode 100644 index 14d95abe..00000000 --- a/spec/javascript/src/__snapshots__/App.test.ts.snap +++ /dev/null @@ -1,43 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`App matches snapshot 1`] = ` -
-
Logo - -
-
Home page
- -
-`; diff --git a/spec/javascript/src/components/GitVersion.test.ts b/spec/javascript/src/components/GitVersion.test.ts deleted file mode 100644 index 65edd4e5..00000000 --- a/spec/javascript/src/components/GitVersion.test.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { mount } from '@vue/test-utils'; -import GitVersion from '@/components/GitVersion.vue'; - -describe('GitVersion', () => { - test('matches snapshot', () => { - const wrapper = mount(GitVersion, { - props: { - commitVersion: 'v0.0.1-123-7654321', - commitTime: '2021-06-01T12:00:00+02:00', - }, - }); - - expect(wrapper.html()).toMatchSnapshot(); - - wrapper.unmount(); - }); -}); diff --git a/spec/javascript/src/components/__snapshots__/GitVersion.test.ts.snap b/spec/javascript/src/components/__snapshots__/GitVersion.test.ts.snap deleted file mode 100644 index ac7ce976..00000000 --- a/spec/javascript/src/components/__snapshots__/GitVersion.test.ts.snap +++ /dev/null @@ -1,3 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`GitVersion matches snapshot 1`] = `
v0.0.1-123-7654321
`; diff --git a/spec/javascript/src/pages/About.test.ts b/spec/javascript/src/pages/About.test.ts deleted file mode 100644 index 1b06a9ad..00000000 --- a/spec/javascript/src/pages/About.test.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { mount } from '@vue/test-utils'; -import AboutPage from '@/pages/AboutPage.vue'; -import * as Vue from 'vue'; - -describe('About', () => { - const savedVersion = Object.getOwnPropertyDescriptor( - Vue, - 'version', - ) as PropertyDescriptor; - - beforeAll(() => { - // Mock `Vue.version` to have a stable snapshot - Object.defineProperty(Vue, 'version', { - value: '3.x.y', - }); - }); - - afterAll(() => { - Object.defineProperty(Vue, 'version', savedVersion); - }); - - test('matches snapshot', () => { - const wrapper = mount(AboutPage, {}); - - expect(wrapper.html()).toMatchSnapshot(); - }); -}); diff --git a/spec/javascript/src/pages/Home.test.ts b/spec/javascript/src/pages/Home.test.ts deleted file mode 100644 index 9ea60df7..00000000 --- a/spec/javascript/src/pages/Home.test.ts +++ /dev/null @@ -1,60 +0,0 @@ -const mockSendClick = jest.fn(); -const mockUnsubscribe = jest.fn(); -const mockGetClicks = jest.fn(); -const mockSubscribe = jest.fn(); - -jest.mock('@/stores/click', () => ({ - __esModule: true, - useClickStore: () => ({ - loaded: true, - total: 42, - items: [ - { - created_at: '2021-05-23T09:27:21.497Z', - ip: '1.2.3.4', - user_agent: 'Jest', - }, - ], - getClicks: mockGetClicks, - subscribe: mockSubscribe, - unsubscribe: mockUnsubscribe, - sendClick: mockSendClick, - }), -})); - -import { mount } from '@vue/test-utils'; -import Home from '@/pages/HomePage.vue'; - -describe('Home', () => { - const wrapper = mount(Home, { - props: { - name: 'World', - }, - }); - - test('load clicks and subscribes', () => { - expect(mockSubscribe).toHaveBeenCalled(); - expect(mockGetClicks).toHaveBeenCalled(); - }); - - test('renders name', () => { - const title = wrapper.find('h1')?.element?.textContent?.trim(); - expect(title).toEqual('Hello, World!'); - }); - - test('matches snapshot', () => { - expect(wrapper.html()).toMatchSnapshot(); - }); - - test('executes sendClick', () => { - const button = wrapper.find('button'); - button.trigger('click'); - - expect(mockSendClick).toHaveBeenCalled(); - }); - - test('unsubscribes on unmount', () => { - wrapper.unmount(); - expect(mockUnsubscribe).toHaveBeenCalled(); - }); -}); diff --git a/spec/javascript/src/pages/NotFound.test.ts b/spec/javascript/src/pages/NotFound.test.ts deleted file mode 100644 index dd552ecb..00000000 --- a/spec/javascript/src/pages/NotFound.test.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { mount } from '@vue/test-utils'; -import NotFound from '@/pages/NotFound.vue'; - -describe('NotFound', () => { - test('matches snapshot', () => { - const wrapper = mount(NotFound, {}); - - expect(wrapper.html()).toMatchSnapshot(); - }); -}); diff --git a/spec/javascript/src/pages/__snapshots__/About.test.ts.snap b/spec/javascript/src/pages/__snapshots__/About.test.ts.snap deleted file mode 100644 index 962ad832..00000000 --- a/spec/javascript/src/pages/__snapshots__/About.test.ts.snap +++ /dev/null @@ -1,265 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`About matches snapshot 1`] = ` -

About

-

Templatus is an opinionated template for web applications with Ruby on Rails and Vue.js 3

-
-
-
-
-

Server side

-

The backend

-
-
-
-
-
-

Ruby - -

-
-
A dynamic, open source programming language with a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write.
-
-
-
-

Ruby on Rails - -

-
-
Rails is a web application development framework written in the Ruby programming language. It is designed to make programming web applications easier by making assumptions about what every developer needs to get started.
-
-
-
-

PostgreSQL - -

-
-
PostgreSQL is a powerful, open source object-relational database system with over 30 years of active development that has earned it a strong reputation for reliability, feature robustness, and performance.
-
-
-
-

Puma - -

-
-
Puma is a simple, fast, multi-threaded, and highly concurrent HTTP 1.1 server for Ruby/Rack applications.
-
-
-
-

Redis - -

-
-
Redis is an open source, in-memory data structure store, used as a database, cache, and message broker.
-
-
-
-

Sidekiq - -

-
-
Simple, efficient background processing for Ruby

Admin frontend

-
-
-
-
-
-
-
-
-
-

Client side

-

The frontend

-
-
-
-
-
-

Vue3.x.y

-
-
Vue is a progressive framework for building user interfaces.
-
-
-
-

Tailwind CSS 3 - -

-
-
A utility-first CSS framework packed with classes that can be composed to build any design, directly in your markup.
-
-
-
-

TypeScript - -

-
-
TypeScript is an open-source language which builds on JavaScript, one of the world’s most used tools, by adding static type definitions.
-
-
-
-

Pinia - -

-
-
Intuitive, type safe, light and flexible Store for Vue using the composition api with DevTools support
-
-
-
-

Heroicons - -

-
-
Beautiful hand-crafted SVG icons, by the makers of Tailwind CSS.
-
-
-
-

Vite - -

-
-
Next generation frontend tooling. It's fast!
-
-
-
-
-
-
-
-
-

Quality insurance

-

Continuous integration

-
-
-
-
-
-

GitHub Actions - -

-
-
Test, build and deliver on every push to GitHub
-
-
-
-

RSpec - -

-
-
Behaviour Driven Development for Ruby. Making TDD Productive and Fun.
-
-
-
-

RuboCop - -

-
-
The Ruby Linter/Formatter that Serves and Protects
-
-
-
-

Jest - -

-
-
Jest is a delightful JavaScript Testing Framework with a focus on simplicity
-
-
-
-

ESLint - -

-
-
ESLint statically analyzes your code to quickly find problems
-
-
-
-

Cypress - -

-
-
Fast, easy and reliable testing for anything that runs in a browser.
-
-
-
-
-
-
-
-
-

Ship it!

-

Deployment

-
-
-
-
-
-

Alpine Linux - -

-
-
Alpine Linux is an independent, non-commercial, general purpose Linux distribution designed for power users who appreciate security, simplicity and resource efficiency.
-
-
-
-

Docker - -

-
-
Dockerized using an optimized base image.
-
-
-
-

Plausible - -

-
-
Plausible is lightweight and open source web analytics. No cookies and fully compliant with GDPR, CCPA and PECR.
-
-
-
-
-
-
-`; diff --git a/spec/javascript/src/pages/__snapshots__/Home.test.ts.snap b/spec/javascript/src/pages/__snapshots__/Home.test.ts.snap deleted file mode 100644 index 94c9ceb5..00000000 --- a/spec/javascript/src/pages/__snapshots__/Home.test.ts.snap +++ /dev/null @@ -1,23 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Home matches snapshot 1`] = ` -
-

Hello, World!

-

Templatus is an opinionated template for web applications with Ruby on Rails and Vue.js 3

-
-
-
- -
42
-
-
Clicks
-
- -
-

Latest clicks

- -
  • -

    1.2.3.4May 23, 2021, 09:27:21

    Jest -
  • -
    -`; diff --git a/spec/javascript/src/pages/__snapshots__/NotFound.test.ts.snap b/spec/javascript/src/pages/__snapshots__/NotFound.test.ts.snap deleted file mode 100644 index 06d1ce45..00000000 --- a/spec/javascript/src/pages/__snapshots__/NotFound.test.ts.snap +++ /dev/null @@ -1,8 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`NotFound matches snapshot 1`] = ` -

    Error 404

    -
    -

    Page not found

    -
    -`; diff --git a/spec/javascript/src/stores/click.test.ts b/spec/javascript/src/stores/click.test.ts deleted file mode 100644 index 508d2fbb..00000000 --- a/spec/javascript/src/stores/click.test.ts +++ /dev/null @@ -1,60 +0,0 @@ -const mockGet = jest.fn().mockResolvedValue({ - json: { - total: 500, - items: [ - { - id: 1, - created_at: '1990-12-25', - ip: '1.2.3.4', - user_agent: 'World Wide Web', - }, - { - id: 2, - created_at: '1994-12-15', - ip: '5.6.7.8', - user_agent: 'Netscape Navigator', - }, - ], - }, -}); - -const mockPost = jest.fn().mockResolvedValue(43); - -jest.mock('@rails/request.js', () => ({ - __esModule: true, - get: mockGet, - post: mockPost, -})); - -import { setActivePinia, createPinia } from 'pinia'; -import { useClickStore } from '@/stores/click'; - -describe('CounterStore', () => { - beforeEach(() => setActivePinia(createPinia())); - - it('can send click', async () => { - const store = useClickStore(); - await store.sendClick(); - - expect(mockPost).toHaveBeenCalled(); - }); - - it('can get clicks', async () => { - const store = useClickStore(); - await store.getClicks(); - - expect(store.total).toEqual(500); - }); - - it('can subscribe', () => { - const store = useClickStore(); - store.subscribe(); - expect(store.subscribed).toEqual(true); - }); - - it('can unsubscribe', () => { - const store = useClickStore(); - store.unsubscribe(); - expect(store.subscribed).toEqual(false); - }); -}); diff --git a/spec/javascript/src/utils/metaContent.test.ts b/spec/javascript/src/utils/metaContent.test.ts deleted file mode 100644 index 5aae0aa2..00000000 --- a/spec/javascript/src/utils/metaContent.test.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { metaContent } from '@/utils/metaContent'; - -describe('metaContent', () => { - beforeAll(() => { - document.head.innerHTML = ''; - }); - - test('returns content when exists', () => { - expect(metaContent('the-name')).toEqual('the-content'); - }); - - test('returns undefined when missing', () => { - expect(metaContent('this-does-not-exist')).toBeUndefined(); - }); -}); diff --git a/spec/javascript/utils/metaContent.test.ts b/spec/javascript/utils/metaContent.test.ts new file mode 100644 index 00000000..57e6b94e --- /dev/null +++ b/spec/javascript/utils/metaContent.test.ts @@ -0,0 +1,32 @@ +import { metaContent, assetUrl } from '@/utils/metaContent'; + +describe('metaContent', () => { + beforeAll(() => { + document.head.innerHTML = ''; + }); + + test('returns content when exists', () => { + expect(metaContent('the-name')).toEqual('the-content'); + }); + + test('returns undefined when missing', () => { + expect(metaContent('this-does-not-exist')).toBeUndefined(); + }); +}); + +describe('assetUrl', () => { + test('adds asset host when exists', () => { + document.head.innerHTML = + ''; + + expect(assetUrl('/assets/logo.svg')).toEqual( + 'https://cdn.example.com/assets/logo.svg', + ); + }); + + test('returns unchanged when missing', () => { + document.head.innerHTML = ''; + + expect(assetUrl('/assets/logo.svg')).toEqual('/assets/logo.svg'); + }); +}); diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 73ccae55..bd75bc73 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -18,6 +18,7 @@ end require 'rspec/rails' # Add additional requires below this line. Rails is not loaded until this point! +require 'inertia_rails/rspec' # Requires supporting ruby files with custom matchers and macros, etc, in # spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are diff --git a/spec/requests/about_spec.rb b/spec/requests/about_spec.rb new file mode 100644 index 00000000..6498948e --- /dev/null +++ b/spec/requests/about_spec.rb @@ -0,0 +1,10 @@ +describe 'About', inertia: true do + describe 'GET /show' do + it 'render features' do + get '/about' + + expect_inertia.to render_component('About/Show') + expect_inertia.to include_props(:features) + end + end +end diff --git a/spec/requests/clicks_spec.rb b/spec/requests/clicks_spec.rb index ca912687..6fb072bd 100644 --- a/spec/requests/clicks_spec.rb +++ b/spec/requests/clicks_spec.rb @@ -1,4 +1,4 @@ -describe 'Clicks' do +describe 'Clicks', inertia: true do include ActiveSupport::Testing::TimeHelpers let(:user_agent) { 'Netscape Navigator' } @@ -12,10 +12,11 @@ def call(ip) headers: { HTTP_USER_AGENT: user_agent, REMOTE_ADDR: ip, - ACCEPT: 'application/json', } - expect(response).to have_http_status(:no_content) + expect_inertia.to render_component('Clicks/Index') + expect_inertia.to have_exact_props({}) + expect(Click.last.user_agent).to eq(user_agent) end @@ -40,27 +41,14 @@ def call(ip) end end - describe 'GET /index' do - around { |example| freeze_time(&example) } - - before { Click.create! ip:, user_agent: } + describe 'GET /' do + let!(:click) { Click.create! ip:, user_agent: } - it 'save click and returns http success' do - get '/clicks', headers: { ACCEPT: 'application/json' } + it 'renders existing clicks' do + get '/' - expect(response).to have_http_status(:success) - expect(JSON.parse(response.body)).to match( - 'total' => 1, - 'items' => [ - hash_including( - { - 'created_at' => Time.current.as_json, - 'ip' => ip, - 'user_agent' => user_agent, - }, - ), - ], - ) + expect_inertia.to render_component('Clicks/Index') + expect_inertia.to have_exact_props(total: 1, items: [click]) end end end diff --git a/spec/requests/deflater_spec.rb b/spec/requests/deflater_spec.rb index 7659a8ba..78a8be63 100644 --- a/spec/requests/deflater_spec.rb +++ b/spec/requests/deflater_spec.rb @@ -1,4 +1,4 @@ -describe 'Rack::Deflater', type: :request do +describe 'Rack::Deflater' do it 'compresses with gzip if requested' do ['gzip', 'deflate, gzip', 'gzip, deflate'].each do |compression_method| get root_path, headers: { HTTP_ACCEPT_ENCODING: compression_method } diff --git a/spec/requests/exceptions_spec.rb b/spec/requests/exceptions_spec.rb new file mode 100644 index 00000000..48a44c00 --- /dev/null +++ b/spec/requests/exceptions_spec.rb @@ -0,0 +1,41 @@ +describe 'Exception handling', type: :request do + describe 'requesting URL which does NOT exist' do + %w[ + /this-does-not-exist + /this/does/not/exist + /index.html + /contribute.json + /docker-compose.yml + /jquery.js + /babel.config.js + /bootstrap.css + /sitemap.xml + /password.txt + /picture.png + /picture.gif + /picture.jpg + /picture.jpeg + /wp-login.php + /.git/config + /../root + ].each do |url| + context "for #{url}" do + it 'returns a 404 status code' do + rails_respond_without_detailed_exceptions { get(url) } + expect(response).to have_http_status(:not_found) + end + end + end + end + + # describe 'requesting URL with unknown format' do + # %w[?format=xml /.env /.git].each do |url| + # context "for #{url}" do + # it 'returns a 406 status code' do + # rails_respond_without_detailed_exceptions { get(url) } + # expect(response).to have_http_status(:not_acceptable) + # end + # end + # end + # end +end diff --git a/spec/support/error_responses.rb b/spec/support/error_responses.rb new file mode 100644 index 00000000..1c5d1dfb --- /dev/null +++ b/spec/support/error_responses.rb @@ -0,0 +1,21 @@ +# How to have Rails request specs handling errors like production +# https://medium.com/@edgar/rspec-how-to-have-rails-request-specs-handling-errors-like-production-a8c21ed0308a + +module ErrorResponses + def rails_respond_without_detailed_exceptions # rubocop:disable Metrics/MethodLength + env_config = Rails.application.env_config + original_show_exceptions = env_config['action_dispatch.show_exceptions'] + original_show_detailed_exceptions = + env_config['action_dispatch.show_detailed_exceptions'] + env_config['action_dispatch.show_exceptions'] = true + env_config['action_dispatch.show_detailed_exceptions'] = false + yield + ensure + env_config['action_dispatch.show_exceptions'] = original_show_exceptions + env_config[ + 'action_dispatch.show_detailed_exceptions' + ] = original_show_detailed_exceptions + end +end + +RSpec.configure { |config| config.include ErrorResponses } diff --git a/svelte.config.js b/svelte.config.js new file mode 100644 index 00000000..2dd36643 --- /dev/null +++ b/svelte.config.js @@ -0,0 +1,5 @@ +const sveltePreprocess = require('svelte-preprocess'); + +module.exports = { + preprocess: sveltePreprocess(), +}; diff --git a/tailwind.config.js b/tailwind.config.js index 984b7d81..3f4a88e5 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -6,8 +6,8 @@ module.exports = { light: '#D30001', dark: '#690000', }, - vue: { - DEFAULT: '#42b883', + inertia: { + DEFAULT: '#9553e9', }, rose: { DEFAULT: '#F0E7E9', @@ -18,7 +18,7 @@ module.exports = { content: [ './app/**/*.{html,rb}', './app/**/*.html.erb', - './app/javascript/**/*.{vue,js,ts}', + './app/javascript/**/*.{svelte,js,ts}', ], plugins: [require('@tailwindcss/forms')], }; diff --git a/tsconfig.json b/tsconfig.json index 856fc13d..a2d2426d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,77 +1,16 @@ { + "extends": "@tsconfig/svelte/tsconfig.json", "compilerOptions": { - /* Visit https://aka.ms/tsconfig.json to read more about this file */ - - /* Basic Options */ - // "incremental": true, /* Enable incremental compilation */ - "target": "esnext", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ - // "lib": [], /* Specify library files to be included in the compilation. */ - // "allowJs": true, /* Allow javascript files to be compiled. */ - // "checkJs": true, /* Report errors in .js files. */ - "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */ - // "declaration": true, /* Generates corresponding '.d.ts' file. */ - // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ - "sourceMap": true, /* Generates corresponding '.map' file. */ - // "outFile": "./", /* Concatenate and emit output to single file. */ - // "outDir": "./", /* Redirect output structure to the directory. */ - // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ - // "composite": true, /* Enable project compilation */ - // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ - "removeComments": true, /* Do not emit comments to output. */ - "noEmit": true, /* Do not emit outputs. */ - "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ - // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* Enable strict null checks. */ - // "strictFunctionTypes": true, /* Enable strict checking of function types. */ - // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ - // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ - // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ - - /* Additional Checks */ - // "noUnusedLocals": true, /* Report errors on unused locals. */ - // "noUnusedParameters": true, /* Report errors on unused parameters. */ - // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ - // "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */ - - /* Module Resolution Options */ - // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + "target": "esNext", + "module": "esNext", + "types": ["vite/client", "jest", "@testing-library/jest-dom"], "paths": { - "@/*": ["./app/javascript/src/*"], - "@test/*": ["./spec/javascript/src/*"] + "@/*": ["./app/javascript/*"], + "@test/*": ["./spec/javascript/*"] }, - // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ - // "typeRoots": [], /* List of folders to include type definitions from. */ - // "types": [], /* Type declaration files to be included in compilation. */ - // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - - /* Source Map Options */ - // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ - // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ - - /* Experimental Options */ - // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ - - /* Advanced Options */ - "skipLibCheck": true, /* Skip type checking of declaration files. */ - "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ + "strict": true, + "noImplicitAny": false, }, - "include": ["app/javascript/**/*.ts", "app/javascript/**/*.vue", "spec/javascript/**/*.ts"], + "include": [ "app/javascript/**/*", "spec/javascript/**/*" ], "exclude": ["node_modules", "public"] } diff --git a/vite.config.ts b/vite.config.ts index 44e62a04..2765b63a 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -2,24 +2,32 @@ import { defineConfig } from 'vite'; import { splitVendorChunkPlugin } from 'vite'; import RubyPlugin from 'vite-plugin-ruby'; import FullReload from 'vite-plugin-full-reload'; -import vue from '@vitejs/plugin-vue'; +import { svelte } from '@sveltejs/vite-plugin-svelte'; import { fileURLToPath, URL } from 'url'; +import preprocess from 'svelte-preprocess'; export default defineConfig({ plugins: [ splitVendorChunkPlugin(), RubyPlugin(), FullReload(['config/routes.rb', 'app/views/**/*']), - vue(), + svelte({ + experimental: { + prebundleSvelteLibraries: true, + }, + preprocess: preprocess({ + postcss: true, + }), + }), ], resolve: { alias: { - '@': fileURLToPath(new URL('./app/javascript/src', import.meta.url)), + '@': fileURLToPath(new URL('./app/javascript', import.meta.url)), }, }, server: { hmr: { - host: 'vite.templatus.test', + host: 'vite.templatus-inertia.test', clientPort: 443, }, }, diff --git a/yarn.lock b/yarn.lock index 94227d94..d58af251 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,7 +10,7 @@ "@jridgewell/gen-mapping" "^0.1.0" "@jridgewell/trace-mapping" "^0.3.9" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.7": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== @@ -22,7 +22,7 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.10.tgz#711dc726a492dfc8be8220028b1b92482362baab" integrity sha512-GZt/TCsG70Ms19gfZO1tM4CVnXsPgEPBCpJu+Qz3L0LUDsY5nZqFZglIoPC1kIYOtNBZlrnFT+klg12vFGZXrw== -"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.18.2": +"@babel/core@^7.11.6", "@babel/core@^7.12.3": version "7.18.2" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.2.tgz#87b2fcd7cce9becaa7f5acebdc4f09f3dd19d876" integrity sha512-A8pri1YJiC5UnkdrWcmfZTJTV85b4UXTAfImGmCfYmax4TR9Cw8sDS0MOk++Gp2mE/BefVJ5nwy5yzqNJbP/DQ== @@ -108,7 +108,7 @@ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.17.12.tgz#86c2347da5acbf5583ba0a10aed4c9bf9da9cf96" integrity sha512-JDkf04mqtN3y4iAbO1hv9U2ARpPyPL1zqyWs/2WG1pgSq9llHFjStX5jdxb84himgJm+8Ng+x0oiWF/nw/XQKA== -"@babel/helper-simple-access@^7.17.7", "@babel/helper-simple-access@^7.18.2": +"@babel/helper-simple-access@^7.17.7": version "7.18.2" resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.18.2.tgz#4dc473c2169ac3a1c9f4a51cfcd091d1c36fcff9" integrity sha512-7LIrjYzndorDY88MycupkpQLKS1AFfsVRm2k/9PtKScSy5tZq0McZTj+DiMRynboZfIqOKvo03pmhTaUgiD6fQ== @@ -150,7 +150,7 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.16.4", "@babel/parser@^7.16.7", "@babel/parser@^7.18.0": +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.16.7", "@babel/parser@^7.18.0": version "7.18.4" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.4.tgz#6774231779dd700e0af29f6ad8d479582d7ce5ef" integrity sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow== @@ -246,15 +246,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.17.12" -"@babel/plugin-transform-modules-commonjs@^7.2.0": - version "7.18.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.2.tgz#1aa8efa2e2a6e818b6a7f2235fceaf09bdb31e9e" - integrity sha512-f5A865gFPAJAEE0K7F/+nm5CmAE3y8AWlMBG9unu5j9+tk50UQVK0QS8RNxSp7MJf0wh97uYyLWt3Zvu71zyOQ== +"@babel/runtime@^7.12.5", "@babel/runtime@^7.9.2": + version "7.18.3" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.3.tgz#c7b654b57f6f63cf7f8b418ac9ca04408c4579f4" + integrity sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug== dependencies: - "@babel/helper-module-transforms" "^7.18.0" - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/helper-simple-access" "^7.18.2" - babel-plugin-dynamic-import-node "^2.3.3" + regenerator-runtime "^0.13.4" "@babel/template@^7.16.7", "@babel/template@^7.3.3": version "7.16.7" @@ -346,25 +343,18 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@heroicons/vue@^1.0.6": - version "1.0.6" - resolved "https://registry.yarnpkg.com/@heroicons/vue/-/vue-1.0.6.tgz#d8b90734b436eb5a87f40cc300b64a0fb0031f7f" - integrity sha512-ng2YcCQrdoQWEFpw+ipFl2rZo8mZ56v0T5+MyfQQvNqfKChwgP6DMloZLW+rl17GEcHkE3H82UTAMKBKZr4+WA== +"@feltcoop/eslint-config@^0.1.7": + version "0.1.7" + resolved "https://registry.yarnpkg.com/@feltcoop/eslint-config/-/eslint-config-0.1.7.tgz#1fbdac20232f0c1cb3686635da0d7a973d4d9a5e" + integrity sha512-NYbSlDVlDY/oPTIwyKNfp8Znouf3Mi2rAYMxphB1jtS9DYJAjvxOfj51ZB+eOo8Gsp3YRdNBr6bULQeKyTAn5g== -"@honeybadger-io/js@^4.0.1": +"@honeybadger-io/js@^4.0.3": version "4.0.3" resolved "https://registry.yarnpkg.com/@honeybadger-io/js/-/js-4.0.3.tgz#56eb7d26ee19aa5ff84942080a1cee0299ad784a" integrity sha512-v1NVtM+vGO6Xe8ZbHs45V8INCasuQK6xSjgPPVNvaL2xgcAKfJhfMnqIqQWtBeu9cGvfAJusiMUiIge68jkQAA== dependencies: stacktrace-parser "^0.1.10" -"@honeybadger-io/vue@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@honeybadger-io/vue/-/vue-3.1.0.tgz#83e12d22e82a3eacc4b28df8731a4af235352f14" - integrity sha512-sSRrw6w64pwhDCTQwYPZl1plM3sFEBfGiDr3cwuNVCzquSZ5niRQI4MkMC+UH21+cO2S6H7ube8UUJ9gazbpTg== - dependencies: - "@honeybadger-io/js" "^4.0.1" - "@humanwhocodes/config-array@^0.9.2": version "0.9.5" resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.5.tgz#2cbaf9a89460da24b5ca6531b8bbfc23e1df50c7" @@ -379,6 +369,29 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== +"@inertiajs/inertia-svelte@^0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@inertiajs/inertia-svelte/-/inertia-svelte-0.8.0.tgz#cb3c1443e354536ad8e92cb3b0e1c839cafd3d4f" + integrity sha512-kitWdsYNUddJlhBKPjOpJPhzOZgcAD4DkIVS2eSPKgCdrbincHHYnj8KlPsIJm8H6frQsB1Wf2sWzblJKS6Mmg== + dependencies: + lodash.isequal "^4.5.0" + +"@inertiajs/inertia@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@inertiajs/inertia/-/inertia-0.11.0.tgz#873ec1283ad4db33b87b4c0e3011c2e5fc3e6cc1" + integrity sha512-QF4hctgFC+B/t/WClCwfOla+WoDE9iTltQJ0u+DCfjl0KdGoCvIxYiNtuH8h8oM+RQMb8orjbpW3pHapjYI5Vw== + dependencies: + axios "^0.21.1" + deepmerge "^4.0.0" + qs "^6.9.0" + +"@inertiajs/progress@^0.2.7": + version "0.2.7" + resolved "https://registry.yarnpkg.com/@inertiajs/progress/-/progress-0.2.7.tgz#b42ac849b6f227fe8a45a91d663719c5bd362131" + integrity sha512-zxadfLlBPIUvTE9g5k71V/Ayzo8P9kEp4hV4UKywCC2kURufxV7bycbZqU1GeMCFGDT+VRrjXNl676Pwwa1HoQ== + dependencies: + nprogress "^0.2.0" + "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" @@ -661,10 +674,13 @@ resolved "https://registry.yarnpkg.com/@rails/actioncable/-/actioncable-7.0.3.tgz#71f08e958883af64f6a20489318b5e95d2c6dc5b" integrity sha512-Iefl21FZD+ck1di6xSHMYzSzRiNJTHV4NrAzCfDfqc/wPz4xncrP8f2/fJ+2jzwKIaDn76UVMsALh7R5OzsF8Q== -"@rails/request.js@^0.0.6": - version "0.0.6" - resolved "https://registry.yarnpkg.com/@rails/request.js/-/request.js-0.0.6.tgz#5f0347a9f363e50ec45118c7134080490cda81d8" - integrity sha512-dfFWaQXitYJ4kxrgGJNhDNXX54/v10YgoJqBMVe6lhqs6a4N9WD7goZJEvwin82TtK8MqUNhwfyisgKwM6dMdg== +"@rollup/pluginutils@^4.2.1": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.2.1.tgz#e6c6c3aba0744edce3fb2074922d3776c0af2a6d" + integrity sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ== + dependencies: + estree-walker "^2.0.1" + picomatch "^2.2.2" "@sinclair/typebox@^0.23.3": version "0.23.5" @@ -692,6 +708,18 @@ dependencies: semver "7.3.5" +"@sveltejs/vite-plugin-svelte@^1.0.0-next.48": + version "1.0.0-next.48" + resolved "https://registry.yarnpkg.com/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-1.0.0-next.48.tgz#6ab566d56c842d45a988cf73c119d0038d4ce893" + integrity sha512-hjCEww6FKSuHVMe56vZLClUDuRqK4A/ZC5hPUIx/o2fQ7HmRydp4ztEopjMMnl/YYyEceGBKgY781I9PGEYvAw== + dependencies: + "@rollup/pluginutils" "^4.2.1" + debug "^4.3.4" + deepmerge "^4.2.2" + kleur "^4.1.4" + magic-string "^0.26.2" + svelte-hmr "^0.14.12" + "@tailwindcss/forms@^0.5.2": version "0.5.2" resolved "https://registry.yarnpkg.com/@tailwindcss/forms/-/forms-0.5.2.tgz#4ef45f9916dcb37838cbe7fecdcc4ba7a7c2ab59" @@ -699,11 +727,62 @@ dependencies: mini-svg-data-uri "^1.2.3" +"@testing-library/dom@^8.1.0", "@testing-library/dom@^8.13.0": + version "8.13.0" + resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-8.13.0.tgz#bc00bdd64c7d8b40841e27a70211399ad3af46f5" + integrity sha512-9VHgfIatKNXQNaZTtLnalIy0jNZzY35a4S3oi08YAt9Hv1VsfZ/DfA45lM8D/UhtHBGJ4/lGwp0PZkVndRkoOQ== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/runtime" "^7.12.5" + "@types/aria-query" "^4.2.0" + aria-query "^5.0.0" + chalk "^4.1.0" + dom-accessibility-api "^0.5.9" + lz-string "^1.4.4" + pretty-format "^27.0.2" + +"@testing-library/jest-dom@^5.16.4": + version "5.16.4" + resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.16.4.tgz#938302d7b8b483963a3ae821f1c0808f872245cd" + integrity sha512-Gy+IoFutbMQcky0k+bqqumXZ1cTGswLsFqmNLzNdSKkU9KGV2u9oXhukCbbJ9/LRPKiqwxEE8VpV/+YZlfkPUA== + dependencies: + "@babel/runtime" "^7.9.2" + "@types/testing-library__jest-dom" "^5.9.1" + aria-query "^5.0.0" + chalk "^3.0.0" + css "^3.0.0" + css.escape "^1.5.1" + dom-accessibility-api "^0.5.6" + lodash "^4.17.15" + redent "^3.0.0" + +"@testing-library/svelte@^3.1.3": + version "3.1.3" + resolved "https://registry.yarnpkg.com/@testing-library/svelte/-/svelte-3.1.3.tgz#a3605a0e98ea04f9ba58ec3d554a9e1a81a4a577" + integrity sha512-pyed3yMnTu7wG9Z4XKoIxdrx52hSEFDC8qUaiSsiSh8tBVj3ZjqEKnV2Nfc0IF2llEkT0B7QOXnOVTLJ3O5RCw== + dependencies: + "@testing-library/dom" "^8.1.0" + +"@testing-library/user-event@^14.2.0": + version "14.2.0" + resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-14.2.0.tgz#8293560f8f80a00383d6c755ec3e0b918acb1683" + integrity sha512-+hIlG4nJS6ivZrKnOP7OGsDu9Fxmryj9vCl8x0ZINtTJcCHs2zLsYif5GzuRiBF2ck5GZG2aQr7Msg+EHlnYVQ== + "@tootallnate/once@2": version "2.0.0" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== +"@tsconfig/svelte@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@tsconfig/svelte/-/svelte-3.0.0.tgz#b06e059209f04c414de0069f2f0e2796d979fc6f" + integrity sha512-pYrtLtOwku/7r1i9AMONsJMVYAtk3hzOfiGNekhtq5tYBGA7unMve8RvUclKLMT3PrihvJqUmzsRGh0RP84hKg== + +"@types/aria-query@^4.2.0": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.2.tgz#ed4e0ad92306a704f9fb132a0cfcf77486dbe2bc" + integrity sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig== + "@types/babel__core@^7.1.14": version "7.1.19" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.19.tgz#7b497495b7d1b4812bdb9d02804d0576f43ee460" @@ -763,7 +842,7 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@^28.1.1": +"@types/jest@*", "@types/jest@^28.1.1": version "28.1.1" resolved "https://registry.yarnpkg.com/@types/jest/-/jest-28.1.1.tgz#8c9ba63702a11f8c386ee211280e8b68cb093cd1" integrity sha512-C2p7yqleUKtCkVjlOur9BWVA4HgUQmEj/HWCt5WzZ5mLXrWnyIfl0wGuArc+kBXsy0ZZfLp+7dywB4HtSVYGVA== @@ -805,11 +884,23 @@ resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.6.3.tgz#68ada76827b0010d0db071f739314fa429943d0a" integrity sha512-ymZk3LEC/fsut+/Q5qejp6R9O1rMxz3XaRHDV6kX8MrGAhOSPqVARbDi+EZvInBpw+BnCX3TD240byVkOfQsHg== +"@types/pug@^2.0.4": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@types/pug/-/pug-2.0.6.tgz#f830323c88172e66826d0bde413498b61054b5a6" + integrity sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg== + "@types/rails__actioncable@^6.1.6": version "6.1.6" resolved "https://registry.yarnpkg.com/@types/rails__actioncable/-/rails__actioncable-6.1.6.tgz#c5427f7ba5a41e41e1237bc943c81d7f44b46167" integrity sha512-/whIczf4uhpac/X19vMRTHOF4reN92I6C4uOmTTtbT1xdesjrStLNQq9v+jexHehc8RENUHk4sXVzwm5PBy2fA== +"@types/sass@^1.16.0": + version "1.43.1" + resolved "https://registry.yarnpkg.com/@types/sass/-/sass-1.43.1.tgz#86bb0168e9e881d7dade6eba16c9ed6d25dc2f68" + integrity sha512-BPdoIt1lfJ6B7rw35ncdwBZrAssjcwzI5LByIrYs+tpXlj/CAkuVdRsgZDdP4lq5EjyWzwxZCqAoFyHKFwp32g== + dependencies: + "@types/node" "*" + "@types/sinonjs__fake-timers@8.1.1": version "8.1.1" resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz#b49c2c70150141a15e0fa7e79cf1f92a72934ce3" @@ -825,15 +916,12 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== -"@types/strip-bom@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/strip-bom/-/strip-bom-3.0.0.tgz#14a8ec3956c2e81edb7520790aecf21c290aebd2" - integrity sha512-xevGOReSYGM7g/kUBZzPqCrR/KYAo+F0yiPc85WFTJa0MSLtyFTVTU6cJu/aV4mid7IffDIWqo69THF2o4JiEQ== - -"@types/strip-json-comments@0.0.30": - version "0.0.30" - resolved "https://registry.yarnpkg.com/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz#9aa30c04db212a9a0649d6ae6fd50accc40748a1" - integrity sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ== +"@types/testing-library__jest-dom@^5.9.1": + version "5.14.3" + resolved "https://registry.yarnpkg.com/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.3.tgz#ee6c7ffe9f8595882ee7bda8af33ae7b8789ef17" + integrity sha512-oKZe+Mf4ioWlMuzVBaXQ9WDnEm1+umLx0InILg+yvZVBBDmzV5KfZyLrCvadtWcx8+916jLmHafcmqqffl+iIw== + dependencies: + "@types/jest" "*" "@types/tough-cookie@*": version "4.0.2" @@ -919,7 +1007,7 @@ semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/utils@5.27.1", "@typescript-eslint/utils@^5.10.0": +"@typescript-eslint/utils@5.27.1": version "5.27.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.27.1.tgz#b4678b68a94bc3b85bf08f243812a6868ac5128f" integrity sha512-mZ9WEn1ZLDaVrhRaYgzbkXBkTPghPFsup8zDbbsYTxC5OmqrFE7skkKS/sraVsLP3TcT3Ki5CSyEFBRkLH/H/w== @@ -939,175 +1027,11 @@ "@typescript-eslint/types" "5.27.1" eslint-visitor-keys "^3.3.0" -"@vitejs/plugin-vue@^2.3.3": - version "2.3.3" - resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-2.3.3.tgz#fbf80cc039b82ac21a1acb0f0478de8f61fbf600" - integrity sha512-SmQLDyhz+6lGJhPELsBdzXGc+AcaT8stgkbiTFGpXPe8Tl1tJaBw1A6pxDqDuRsVkD8uscrkx3hA7QDOoKYtyw== - -"@volar/code-gen@0.37.3": - version "0.37.3" - resolved "https://registry.yarnpkg.com/@volar/code-gen/-/code-gen-0.37.3.tgz#d76c0a112a7fcba90436f7ab0f2149fae02d66b8" - integrity sha512-+XXfbkjVoDPxECkAOtRmHKnKnSWMOeThqlVSm9XwIVSdyiBN8Gi4xDUWmPH/WxK+D8bGLCm4Vkjk3rge+KOVaQ== - dependencies: - "@volar/source-map" "0.37.3" - -"@volar/source-map@0.37.3": - version "0.37.3" - resolved "https://registry.yarnpkg.com/@volar/source-map/-/source-map-0.37.3.tgz#15c6fa6642c001aff0468a007f9be263e23acb78" - integrity sha512-vedJWjcjKY2u8EnYMQyDjab2+S1tzUqvzJAY3PqVeN7nwJMyP5X2C/OMB2qZqJPxM0EYIR5ExVaJyVxWNkCgYA== - -"@volar/typescript-faster@0.37.3": - version "0.37.3" - resolved "https://registry.yarnpkg.com/@volar/typescript-faster/-/typescript-faster-0.37.3.tgz#b234ea6ff4c134988fcb308d3cb5dc99a9376aca" - integrity sha512-WlEv38Uga/VnstM2cdCedaH8eZsO/DwDr5GDNoJk+lLcpCHbmWgccajUaiLhXfgqBZld0hxQwlgwIqOsKrSgig== - dependencies: - semver "^7.3.7" - -"@volar/vue-code-gen@0.37.3": - version "0.37.3" - resolved "https://registry.yarnpkg.com/@volar/vue-code-gen/-/vue-code-gen-0.37.3.tgz#e872dbf2080aed215d34b58cc41bfb8288b2ddda" - integrity sha512-+V+XUItSKve98W7m+WM1iUHyEe5JixTmILsMqZNJ/Ob0UFci2YD3tCTlMC9/o/CdKlxBCgUerQZ61q/YLWKgkg== - dependencies: - "@volar/code-gen" "0.37.3" - "@volar/source-map" "0.37.3" - "@vue/compiler-core" "^3.2.37" - "@vue/compiler-dom" "^3.2.37" - "@vue/shared" "^3.2.37" - -"@volar/vue-typescript@0.37.3": - version "0.37.3" - resolved "https://registry.yarnpkg.com/@volar/vue-typescript/-/vue-typescript-0.37.3.tgz#b84ebee5604c1d41aa7c89cd71451a4b48438afe" - integrity sha512-klMYVD4a3M+PhjNfreOFjgdGWTFSOM7fIJ5yebrwt8UD9HV2Bhfz0YNTYBL6SkGDTRCgeNPdGTgh1RbIWjsQJA== - dependencies: - "@volar/code-gen" "0.37.3" - "@volar/source-map" "0.37.3" - "@volar/typescript-faster" "0.37.3" - "@volar/vue-code-gen" "0.37.3" - "@vue/compiler-sfc" "^3.2.37" - "@vue/reactivity" "^3.2.37" - -"@vue/compiler-core@3.2.37", "@vue/compiler-core@^3.2.37": - version "3.2.37" - resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.2.37.tgz#b3c42e04c0e0f2c496ff1784e543fbefe91e215a" - integrity sha512-81KhEjo7YAOh0vQJoSmAD68wLfYqJvoiD4ulyedzF+OEk/bk6/hx3fTNVfuzugIIaTrOx4PGx6pAiBRe5e9Zmg== - dependencies: - "@babel/parser" "^7.16.4" - "@vue/shared" "3.2.37" - estree-walker "^2.0.2" - source-map "^0.6.1" - -"@vue/compiler-dom@3.2.37", "@vue/compiler-dom@^3.2.37": - version "3.2.37" - resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.37.tgz#10d2427a789e7c707c872da9d678c82a0c6582b5" - integrity sha512-yxJLH167fucHKxaqXpYk7x8z7mMEnXOw3G2q62FTkmsvNxu4FQSu5+3UMb+L7fjKa26DEzhrmCxAgFLLIzVfqQ== - dependencies: - "@vue/compiler-core" "3.2.37" - "@vue/shared" "3.2.37" - -"@vue/compiler-sfc@3.2.37", "@vue/compiler-sfc@^3.2.37": - version "3.2.37" - resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.37.tgz#3103af3da2f40286edcd85ea495dcb35bc7f5ff4" - integrity sha512-+7i/2+9LYlpqDv+KTtWhOZH+pa8/HnX/905MdVmAcI/mPQOBwkHHIzrsEsucyOIZQYMkXUiTkmZq5am/NyXKkg== - dependencies: - "@babel/parser" "^7.16.4" - "@vue/compiler-core" "3.2.37" - "@vue/compiler-dom" "3.2.37" - "@vue/compiler-ssr" "3.2.37" - "@vue/reactivity-transform" "3.2.37" - "@vue/shared" "3.2.37" - estree-walker "^2.0.2" - magic-string "^0.25.7" - postcss "^8.1.10" - source-map "^0.6.1" - -"@vue/compiler-ssr@3.2.37": - version "3.2.37" - resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.2.37.tgz#4899d19f3a5fafd61524a9d1aee8eb0505313cff" - integrity sha512-7mQJD7HdXxQjktmsWp/J67lThEIcxLemz1Vb5I6rYJHR5vI+lON3nPGOH3ubmbvYGt8xEUaAr1j7/tIFWiEOqw== - dependencies: - "@vue/compiler-dom" "3.2.37" - "@vue/shared" "3.2.37" - -"@vue/devtools-api@^6.0.0", "@vue/devtools-api@^6.1.4": - version "6.1.4" - resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.1.4.tgz#b4aec2f4b4599e11ba774a50c67fa378c9824e53" - integrity sha512-IiA0SvDrJEgXvVxjNkHPFfDx6SXw0b/TUkqMcDZWNg9fnCAHbTpoo59YfJ9QLFkwa3raau5vSlRVzMSLDnfdtQ== - -"@vue/reactivity-transform@3.2.37": - version "3.2.37" - resolved "https://registry.yarnpkg.com/@vue/reactivity-transform/-/reactivity-transform-3.2.37.tgz#0caa47c4344df4ae59f5a05dde2a8758829f8eca" - integrity sha512-IWopkKEb+8qpu/1eMKVeXrK0NLw9HicGviJzhJDEyfxTR9e1WtpnnbYkJWurX6WwoFP0sz10xQg8yL8lgskAZg== - dependencies: - "@babel/parser" "^7.16.4" - "@vue/compiler-core" "3.2.37" - "@vue/shared" "3.2.37" - estree-walker "^2.0.2" - magic-string "^0.25.7" - -"@vue/reactivity@3.2.37", "@vue/reactivity@^3.2.37": - version "3.2.37" - resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.2.37.tgz#5bc3847ac58828e2b78526e08219e0a1089f8848" - integrity sha512-/7WRafBOshOc6m3F7plwzPeCu/RCVv9uMpOwa/5PiY1Zz+WLVRWiy0MYKwmg19KBdGtFWsmZ4cD+LOdVPcs52A== - dependencies: - "@vue/shared" "3.2.37" - -"@vue/runtime-core@3.2.37": - version "3.2.37" - resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.2.37.tgz#7ba7c54bb56e5d70edfc2f05766e1ca8519966e3" - integrity sha512-JPcd9kFyEdXLl/i0ClS7lwgcs0QpUAWj+SKX2ZC3ANKi1U4DOtiEr6cRqFXsPwY5u1L9fAjkinIdB8Rz3FoYNQ== - dependencies: - "@vue/reactivity" "3.2.37" - "@vue/shared" "3.2.37" - -"@vue/runtime-dom@3.2.37": - version "3.2.37" - resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.2.37.tgz#002bdc8228fa63949317756fb1e92cdd3f9f4bbd" - integrity sha512-HimKdh9BepShW6YozwRKAYjYQWg9mQn63RGEiSswMbW+ssIht1MILYlVGkAGGQbkhSh31PCdoUcfiu4apXJoPw== - dependencies: - "@vue/runtime-core" "3.2.37" - "@vue/shared" "3.2.37" - csstype "^2.6.8" - -"@vue/server-renderer@3.2.37": - version "3.2.37" - resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.2.37.tgz#840a29c8dcc29bddd9b5f5ffa22b95c0e72afdfc" - integrity sha512-kLITEJvaYgZQ2h47hIzPh2K3jG8c1zCVbp/o/bzQOyvzaKiCquKS7AaioPI28GNxIsE/zSx+EwWYsNxDCX95MA== - dependencies: - "@vue/compiler-ssr" "3.2.37" - "@vue/shared" "3.2.37" - -"@vue/shared@3.2.37", "@vue/shared@^3.2.37": - version "3.2.37" - resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.37.tgz#8e6adc3f2759af52f0e85863dfb0b711ecc5c702" - integrity sha512-4rSJemR2NQIo9Klm1vabqWjD8rs/ZaJSzMxkMNeJS6lHiUjjUeYFbooN19NgFjztubEKh3WlZUeOLVdbbUWHsw== - -"@vue/test-utils@2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-2.0.0.tgz#06455934091d237d71d81bac6617485de38b1c58" - integrity sha512-zL5kygNq7hONrO1CzaUGprEAklAX+pH8J1MPMCU3Rd2xtSYkZ+PmKU3oEDRg8VAGdL5lNJHzDgrud5amFPtirw== - -"@vue/vue3-jest@^28.0.0": - version "28.0.0" - resolved "https://registry.yarnpkg.com/@vue/vue3-jest/-/vue3-jest-28.0.0.tgz#e1b5d37992dd611a798a0fd0e18b4252aa722c47" - integrity sha512-X5ZgZuG4d9N6x5lZAWWtTCSo4lO6+ytV5IekoyWVQYC9sKbYenrGUrCvy/kSftK6kPe8K/LeSsYj2VMJAUdeww== - dependencies: - "@babel/plugin-transform-modules-commonjs" "^7.2.0" - chalk "^2.1.0" - convert-source-map "^1.6.0" - css-tree "^2.0.1" - source-map "0.5.6" - tsconfig "^7.0.0" - abab@^2.0.5, abab@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - acorn-globals@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" @@ -1236,6 +1160,11 @@ argparse@^2.0.1: resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== +aria-query@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.0.0.tgz#210c21aaf469613ee8c9a62c7f86525e058db52c" + integrity sha512-V+SM7AbUwJ+EBnB8+DXs0hPZHO0W6pqBcc0dW90OwtVG02PswOu/teuARoLQjdDOH+t9pJgGnW5/Qmouf3gPJg== + array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" @@ -1273,6 +1202,11 @@ at-least-node@^1.0.0: resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + autoprefixer@^10.4.7: version "10.4.7" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.7.tgz#1db8d195f41a52ca5069b7593be167618edbbedf" @@ -1295,6 +1229,13 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== +axios@^0.21.1: + version "0.21.4" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" + integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== + dependencies: + follow-redirects "^1.14.0" + babel-jest@^28.1.1: version "28.1.1" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-28.1.1.tgz#2a3a4ae50964695b2d694ccffe4bec537c5a3586" @@ -1308,13 +1249,6 @@ babel-jest@^28.1.1: graceful-fs "^4.2.9" slash "^3.0.0" -babel-plugin-dynamic-import-node@^2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" - integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== - dependencies: - object.assign "^4.1.0" - babel-plugin-istanbul@^6.1.1: version "6.1.1" resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" @@ -1394,11 +1328,6 @@ bluebird@^3.7.2: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== -boolbase@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" - integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== - brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -1444,7 +1373,7 @@ bser@2.1.1: dependencies: node-int64 "^0.4.0" -buffer-crc32@~0.2.3: +buffer-crc32@^0.2.5, buffer-crc32@~0.2.3: version "0.2.13" resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== @@ -1501,16 +1430,16 @@ camelcase@^6.2.0: integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-lite@^1.0.30001335, caniuse-lite@^1.0.30001349: - version "1.0.30001350" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001350.tgz#f0acc6472469d066a4357765eb73be5973eda918" - integrity sha512-NZBql38Pzd+rAu5SPXv+qmTWGQuFsRiemHCJCAPvkoDxWV19/xqL2YHF32fDJ9SDLdLqfax8+S0CO3ncDCp9Iw== + version "1.0.30001351" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001351.tgz#fd38e07c0ab75921169bac5076b0e0c5f58f9b50" + integrity sha512-u+Ll+RDaiQEproTQjZLjZwyfNgNezA1fERMT7/54npcz+PkbVJUAHXMUz4bkXQYRPWrcFNO0Fbi1mwjfXg6N5g== caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== -chalk@^2.0.0, chalk@^2.1.0: +chalk@^2.0.0: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -1519,6 +1448,14 @@ chalk@^2.0.0, chalk@^2.1.0: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +chalk@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" + integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + chalk@^4.0.0, chalk@^4.1.0: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" @@ -1651,11 +1588,6 @@ combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -commander@^2.19.0: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - commander@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" @@ -1671,23 +1603,6 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== -condense-newlines@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/condense-newlines/-/condense-newlines-0.2.1.tgz#3de985553139475d32502c83b02f60684d24c55f" - integrity sha512-P7X+QL9Hb9B/c8HI5BFFKmjgBu2XpQuF98WZ9XkO+dBGgk5XgwiQz7o1SmpglNWId3581UcS0SFAWfoIhMHPfg== - dependencies: - extend-shallow "^2.0.1" - is-whitespace "^0.3.0" - kind-of "^3.0.2" - -config-chain@^1.1.13: - version "1.1.13" - resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4" - integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ== - dependencies: - ini "^1.3.4" - proto-list "~1.2.1" - convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: version "1.8.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" @@ -1709,13 +1624,19 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" -css-tree@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.1.0.tgz#170e27ccf94e7c5facb183765c25898be843d1d2" - integrity sha512-PcysZRzToBbrpoUrZ9qfblRIRf8zbEAkU0AIpQFtgkFK0vSbzOmBCvdSAx2Zg7Xx5wiYJKUKk0NMP7kxevie/A== +css.escape@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" + integrity sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg== + +css@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/css/-/css-3.0.0.tgz#4447a4d58fdd03367c516ca9f64ae365cee4aa5d" + integrity sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ== dependencies: - mdn-data "2.0.27" - source-map-js "^1.0.1" + inherits "^2.0.4" + source-map "^0.6.1" + source-map-resolve "^0.6.0" cssesc@^3.0.0: version "3.0.0" @@ -1739,11 +1660,6 @@ cssstyle@^2.3.0: dependencies: cssom "~0.3.6" -csstype@^2.6.8: - version "2.6.20" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.20.tgz#9229c65ea0b260cf4d3d997cb06288e36a8d6dda" - integrity sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA== - cypress@^10.0.3: version "10.0.3" resolved "https://registry.yarnpkg.com/cypress/-/cypress-10.0.3.tgz#889b4bef863b7d1ef1b608b85b964394ad350c5f" @@ -1832,6 +1748,11 @@ decimal.js@^10.3.1: resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og== + dedent@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" @@ -1842,19 +1763,11 @@ deep-is@^0.1.3, deep-is@~0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== -deepmerge@^4.2.2: +deepmerge@^4.0.0, deepmerge@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== -define-properties@^1.1.3: - version "1.1.4" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" - integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== - dependencies: - has-property-descriptors "^1.0.0" - object-keys "^1.1.1" - defined@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" @@ -1865,6 +1778,11 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== +detect-indent@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.1.0.tgz#592485ebbbf6b3b1ab2be175c8393d04ca0d57e6" + integrity sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA== + detect-newline@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" @@ -1913,6 +1831,11 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" +dom-accessibility-api@^0.5.6, dom-accessibility-api@^0.5.9: + version "0.5.14" + resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.14.tgz#56082f71b1dc7aac69d83c4285eef39c15d93f56" + integrity sha512-NMt+m9zFMPZe0JcY9gN224Qvk6qLIdqex29clBvc/y75ZBX9YA9wNK3frsYvu2DI1xcCIwxwnX+TlsJ2DSOADg== + domexception@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/domexception/-/domexception-4.0.0.tgz#4ad1be56ccadc86fc76d033353999a8037d03673" @@ -1928,20 +1851,10 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" -editorconfig@^0.15.3: - version "0.15.3" - resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-0.15.3.tgz#bef84c4e75fb8dcb0ce5cee8efd51c15999befc5" - integrity sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g== - dependencies: - commander "^2.19.0" - lru-cache "^4.1.5" - semver "^5.6.0" - sigmund "^1.0.1" - electron-to-chromium@^1.4.147: - version "1.4.148" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.148.tgz#437430e03c58ccd1d05701f66980afe54d2253ec" - integrity sha512-8MJk1bcQUAYkuvCyWZxaldiwoDG0E0AMzBGA6cv3WfuvJySiPgfidEPBFCRRH3cZm6SVZwo/oRlK1ehi1QNEIQ== + version "1.4.150" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.150.tgz#89f0e12505462d5df7e56c5b91aff7e1dfdd33ec" + integrity sha512-MP3oBer0X7ZeS9GJ0H6lmkn561UxiwOIY9TTkdxVY7lI9G6GVCKfgJaHaDcakwdKxBXA4T3ybeswH/WBIN/KTA== emittery@^0.10.2: version "0.10.2" @@ -1974,6 +1887,11 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" +es6-promise@^3.1.2: + version "3.3.1" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.3.1.tgz#a08cdde84ccdbf34d027a1451bc91d4bcd28a613" + integrity sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg== + esbuild-android-64@0.14.43: version "0.14.43" resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.14.43.tgz#59bf3edad6863c27aa92bbb5c1d83a9a5c981495" @@ -2144,13 +2062,6 @@ eslint-plugin-cypress@^2.12.1: dependencies: globals "^11.12.0" -eslint-plugin-jest@^26.5.3: - version "26.5.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-26.5.3.tgz#a3ceeaf4a757878342b8b00eca92379b246e5505" - integrity sha512-sICclUqJQnR1bFRZGLN2jnSVsYOsmPYYnroGCIMVSvTS3y8XR3yjzy1EcTQmk6typ5pRgyIWzbjqxK6cZHEZuQ== - dependencies: - "@typescript-eslint/utils" "^5.10.0" - eslint-plugin-prettier@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.0.0.tgz#8b99d1e4b8b24a762472b4567992023619cb98e0" @@ -2158,18 +2069,10 @@ eslint-plugin-prettier@^4.0.0: dependencies: prettier-linter-helpers "^1.0.0" -eslint-plugin-vue@^9.1.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-9.1.0.tgz#b528941325e26a24bc5d5c5030c0a8996c36659c" - integrity sha512-EPCeInPicQ/YyfOWJDr1yfEeSNoFCMzUus107lZyYi37xejdOolNzS5MXGXp8+9bkoKZMdv/1AcZzQebME6r+g== - dependencies: - eslint-utils "^3.0.0" - natural-compare "^1.4.0" - nth-check "^2.0.1" - postcss-selector-parser "^6.0.9" - semver "^7.3.5" - vue-eslint-parser "^9.0.1" - xml-name-validator "^4.0.0" +eslint-plugin-svelte3@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-svelte3/-/eslint-plugin-svelte3-4.0.0.tgz#3d4f3dcaec5761dac8bc697f81de3613b485b4e3" + integrity sha512-OIx9lgaNzD02+MDFNLw0GEUbuovNcglg+wnd/UY0fbZmlQSz7GlQiQ1f+yX0XvC07XPcDOnFcichqI3xCwp71g== eslint-scope@^5.1.1: version "5.1.1" @@ -2245,7 +2148,7 @@ eslint@^8.17.0: text-table "^0.2.0" v8-compile-cache "^2.0.3" -espree@^9.3.1, espree@^9.3.2: +espree@^9.3.2: version "9.3.2" resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.2.tgz#f58f77bd334731182801ced3380a8cc859091596" integrity sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA== @@ -2283,7 +2186,7 @@ estraverse@^5.1.0, estraverse@^5.2.0: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== -estree-walker@^2.0.2: +estree-walker@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== @@ -2351,13 +2254,6 @@ expect@^28.1.1: jest-message-util "^28.1.1" jest-util "^28.1.1" -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - integrity sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug== - dependencies: - is-extendable "^0.1.0" - extend@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" @@ -2478,6 +2374,11 @@ flatted@^3.1.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== +follow-redirects@^1.14.0: + version "1.15.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5" + integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA== + forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" @@ -2546,14 +2447,14 @@ get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" - integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== +get-intrinsic@^1.0.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz#336975123e05ad0b7ba41f152ee4aadbea6cf598" + integrity sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA== dependencies: function-bind "^1.1.1" has "^1.0.3" - has-symbols "^1.0.1" + has-symbols "^1.0.3" get-package-type@^0.1.0: version "0.1.0" @@ -2643,7 +2544,7 @@ globby@^11.1.0: merge2 "^1.4.1" slash "^3.0.0" -graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.9: +graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.9: version "4.2.10" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== @@ -2658,14 +2559,7 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-property-descriptors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" - integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== - dependencies: - get-intrinsic "^1.1.1" - -has-symbols@^1.0.1: +has-symbols@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== @@ -2776,7 +2670,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2: +inherits@2, inherits@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -2786,11 +2680,6 @@ ini@2.0.0: resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== -ini@^1.3.4: - version "1.3.8" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" - integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== - is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" @@ -2803,11 +2692,6 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== - is-ci@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.1.tgz#db6ecbed1bd659c43dac0f45661e7674103d1867" @@ -2822,11 +2706,6 @@ is-core-module@^2.8.1: dependencies: has "^1.0.3" -is-extendable@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== - is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -2887,11 +2766,6 @@ is-unicode-supported@^0.1.0: resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== -is-whitespace@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/is-whitespace/-/is-whitespace-0.3.0.tgz#1639ecb1be036aec69a54cbb401cfbed7114ab7f" - integrity sha512-RydPhl4S6JwAyj0JJjshWJEFG6hNye3pZFBRZaTUfZFwGHxzppNaNOVgQuS/E/SlhrApuMXrpnK1EEIXfdo3Dg== - isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -3255,13 +3129,6 @@ jest-runtime@^28.1.1: slash "^3.0.0" strip-bom "^4.0.0" -jest-serializer-vue@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/jest-serializer-vue/-/jest-serializer-vue-2.0.2.tgz#b238ef286357ec6b480421bd47145050987d59b3" - integrity sha512-nK/YIFo6qe3i9Ge+hr3h4PpRehuPPGZFt8LDBdTHYldMb7ZWlkanZS8Ls7D8h6qmQP2lBQVDLP0DKn5bJ9QApQ== - dependencies: - pretty "2.0.0" - jest-snapshot@^28.1.1: version "28.1.1" resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-28.1.1.tgz#ab825c16c8d8b5e883bd57eee6ca8748c42ab848" @@ -3353,16 +3220,6 @@ jest@^28.1.1: import-local "^3.0.2" jest-cli "^28.1.1" -js-beautify@^1.6.12: - version "1.14.3" - resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.14.3.tgz#3dd11c949178de7f3bdf3f6f752778d3bed95150" - integrity sha512-f1ra8PHtOEu/70EBnmiUlV8nJePS58y9qKjl4JHfYWlFH6bo7ogZBz//FAZp7jDuXtYnGYKymZPlrg2I/9Zo4g== - dependencies: - config-chain "^1.1.13" - editorconfig "^0.15.3" - glob "^7.1.3" - nopt "^5.0.0" - js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -3475,18 +3332,16 @@ jsprim@^2.0.2: json-schema "0.4.0" verror "1.10.0" -kind-of@^3.0.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== - dependencies: - is-buffer "^1.1.5" - kleur@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== +kleur@^4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.4.tgz#8c202987d7e577766d039a8cd461934c01cda04d" + integrity sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA== + lazy-ass@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/lazy-ass/-/lazy-ass-1.6.0.tgz#7999655e8646c17f089fdd187d150d3324d54513" @@ -3544,6 +3399,11 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" +lodash.isequal@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ== + lodash.memoize@4.x: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" @@ -3559,7 +3419,7 @@ lodash.once@^4.1.1: resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== -lodash@^4.17.21: +lodash@^4.17.15, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -3582,14 +3442,6 @@ log-update@^4.0.0: slice-ansi "^4.0.0" wrap-ansi "^6.2.0" -lru-cache@^4.1.5: - version "4.1.5" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" - integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -3597,6 +3449,11 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +lz-string@^1.4.4: + version "1.4.4" + resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26" + integrity sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ== + magic-string@^0.25.7: version "0.25.9" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c" @@ -3604,6 +3461,13 @@ magic-string@^0.25.7: dependencies: sourcemap-codec "^1.4.8" +magic-string@^0.26.2: + version "0.26.2" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.26.2.tgz#5331700e4158cd6befda738bb6b0c7b93c0d4432" + integrity sha512-NzzlXpclt5zAbmo6h6jNc8zl2gNRGHvmsZW4IvZhTC4W7k4OlLP+S5YLussa/r3ixNT66KOQfNORlXHSOy/X4A== + dependencies: + sourcemap-codec "^1.4.8" + make-dir@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" @@ -3623,11 +3487,6 @@ makeerror@1.0.12: dependencies: tmpl "1.0.5" -mdn-data@2.0.27: - version "2.0.27" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.27.tgz#1710baa7b0db8176d3b3d565ccb7915fc69525ab" - integrity sha512-kwqO0I0jtWr25KcfLm9pia8vLZ8qoAKhWZuZMbneJq3jjBD3gl5nZs8l8Tu3ZBlBAHVQtDur9rdDGyvtfVraHQ== - merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" @@ -3663,6 +3522,11 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +min-indent@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" + integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== + mini-svg-data-uri@^1.2.3: version "1.4.4" resolved "https://registry.yarnpkg.com/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz#8ab0aabcdf8c29ad5693ca595af19dd2ead09939" @@ -3675,11 +3539,18 @@ minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" -minimist@^1.2.6: +minimist@^1.2.0, minimist@^1.2.6: version "1.2.6" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== +mkdirp@^0.5.1: + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + mkdirp@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" @@ -3722,13 +3593,6 @@ node-releases@^2.0.5: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.5.tgz#280ed5bc3eba0d96ce44897d8aee478bfb3d9666" integrity sha512-U9h1NLROZTq9uE1SNffn6WuPDg8icmi3ns4rEl/oTfIle4iLjTliCzgTsbaIFMq/Xn078/lfY/BL0GWZ+psK4Q== -nopt@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" - integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== - dependencies: - abbrev "1" - 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" @@ -3746,12 +3610,10 @@ npm-run-path@^4.0.0, npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" -nth-check@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" - integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== - dependencies: - boolbase "^1.0.0" +nprogress@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/nprogress/-/nprogress-0.2.0.tgz#cb8f34c53213d895723fcbab907e9422adbcafb1" + integrity sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA== nwsapi@^2.2.0: version "2.2.0" @@ -3763,20 +3625,10 @@ object-hash@^3.0.0: resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-3.0.0.tgz#73f97f753e7baffc0e2cc9d6e079079744ac82e9" integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== -object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object.assign@^4.1.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" - integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - has-symbols "^1.0.1" - object-keys "^1.1.1" +object-inspect@^1.9.0: + version "1.12.2" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" + integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" @@ -3909,7 +3761,7 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.1: +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.2.3, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== @@ -3919,14 +3771,6 @@ pify@^2.2.0: resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== -pinia@^2.0.14: - version "2.0.14" - resolved "https://registry.yarnpkg.com/pinia/-/pinia-2.0.14.tgz#0837898c20291ebac982bbfca95c8d3c6099925f" - integrity sha512-0nPuZR4TetT/WcLN+feMSjWJku3SQU7dBbXC6uw+R6FLQJCsg+/0pzXyD82T1FmAYe0lsx+jnEDQ1BLgkRKlxA== - dependencies: - "@vue/devtools-api" "^6.1.4" - vue-demi "*" - pirates@^4.0.4: version "4.0.5" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" @@ -3966,7 +3810,7 @@ postcss-nested@5.0.6: dependencies: postcss-selector-parser "^6.0.6" -postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.6, postcss-selector-parser@^6.0.9: +postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.6: version "6.0.10" resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d" integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w== @@ -3979,7 +3823,7 @@ postcss-value-parser@^4.2.0: resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss@^8.1.10, postcss@^8.4.12, postcss@^8.4.13, postcss@^8.4.14: +postcss@^8.4.12, postcss@^8.4.13, postcss@^8.4.14: version "8.4.14" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.14.tgz#ee9274d5622b4858c1007a74d76e42e56fd21caf" integrity sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig== @@ -4005,6 +3849,11 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" +prettier-plugin-svelte@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/prettier-plugin-svelte/-/prettier-plugin-svelte-2.7.0.tgz#ecfa4fe824238a4466a3497df1a96d15cf43cabb" + integrity sha512-fQhhZICprZot2IqEyoiUYLTRdumULGRvw0o4dzl5jt0jfzVWdGqeYW27QTWAeXhoupEZJULmNoH3ueJwUWFLIA== + prettier-plugin-tailwindcss@^0.1.11: version "0.1.11" resolved "https://registry.yarnpkg.com/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.1.11.tgz#6112da68d9d022b7f896d35c070464931c99c35f" @@ -4020,7 +3869,7 @@ pretty-bytes@^5.6.0: resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== -pretty-format@^27.0.0, pretty-format@^27.5.1: +pretty-format@^27.0.0, pretty-format@^27.0.2, pretty-format@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== @@ -4039,15 +3888,6 @@ pretty-format@^28.1.1: ansi-styles "^5.0.0" react-is "^18.0.0" -pretty@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pretty/-/pretty-2.0.0.tgz#adbc7960b7bbfe289a557dc5f737619a220d06a5" - integrity sha512-G9xUchgTEiNpormdYBl+Pha50gOUovT18IvAe7EYMZ1/f9W/WWMPRn+xI68yXNMUk3QXHDwo/1wV/4NejVNe1w== - dependencies: - condense-newlines "^0.2.1" - extend-shallow "^2.0.1" - js-beautify "^1.6.12" - prompts@^2.0.1: version "2.4.2" resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" @@ -4056,21 +3896,11 @@ prompts@^2.0.1: kleur "^3.0.3" sisteransi "^1.0.5" -proto-list@~1.2.1: - version "1.2.4" - resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" - integrity sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA== - proxy-from-env@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.0.0.tgz#33c50398f70ea7eb96d21f7b817630a55791c7ee" integrity sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A== -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ== - psl@^1.1.28, psl@^1.1.33: version "1.8.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" @@ -4089,6 +3919,13 @@ punycode@^2.1.0, punycode@^2.1.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== +qs@^6.9.0: + version "6.10.5" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.5.tgz#974715920a80ff6a262264acd2c7e6c2a53282b4" + integrity sha512-O5RlPh0VFtR78y79rgcgKK4wbAI0C5zGVLztOIdpWX6ep368q5Hv6XRxDvXuZ9q3C6v+e3n8UfZZJw7IIG27eQ== + dependencies: + side-channel "^1.0.4" + qs@~6.5.2: version "6.5.3" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" @@ -4121,16 +3958,24 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" +redent@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" + integrity sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg== + dependencies: + indent-string "^4.0.0" + strip-indent "^3.0.0" + +regenerator-runtime@^0.13.4: + version "0.13.9" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" + integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== + regexpp@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== -register-service-worker@^1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/register-service-worker/-/register-service-worker-1.7.2.tgz#6516983e1ef790a98c4225af1216bc80941a4bd2" - integrity sha512-CiD3ZSanZqcMPRhtfct5K9f7i3OLCcBBWsJjLh1gW9RO/nS94sVzY59iS+fgYBOBqaBpf4EzfqUF3j9IG+xo8A== - request-progress@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/request-progress/-/request-progress-3.0.0.tgz#4ca754081c7fec63f505e4faa825aa06cd669dbe" @@ -4192,6 +4037,13 @@ rfdc@^1.3.0: resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== +rimraf@^2.5.2: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" @@ -4240,6 +4092,16 @@ safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +sander@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/sander/-/sander-0.5.1.tgz#741e245e231f07cafb6fdf0f133adfa216a502ad" + integrity sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA== + dependencies: + es6-promise "^3.1.2" + graceful-fs "^4.1.3" + mkdirp "^0.5.1" + rimraf "^2.5.2" + saxes@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" @@ -4254,18 +4116,13 @@ semver@7.3.5: dependencies: lru-cache "^6.0.0" -semver@7.x, semver@^7.3.2, semver@^7.3.5, semver@^7.3.6, semver@^7.3.7: +semver@7.x, semver@^7.3.2, semver@^7.3.5, semver@^7.3.7: version "7.3.7" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== dependencies: lru-cache "^6.0.0" -semver@^5.6.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - semver@^6.0.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" @@ -4283,10 +4140,14 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -sigmund@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" - integrity sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA= +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" @@ -4335,11 +4196,29 @@ slice-ansi@^4.0.0: astral-regex "^2.0.0" is-fullwidth-code-point "^3.0.0" -source-map-js@^1.0.1, source-map-js@^1.0.2: +sorcery@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/sorcery/-/sorcery-0.10.0.tgz#8ae90ad7d7cb05fc59f1ab0c637845d5c15a52b7" + integrity sha512-R5ocFmKZQFfSTstfOtHjJuAwbpGyf9qjQa1egyhvXSbM7emjrtLXtGdZsDJDABC85YBfVvrOiGWKSYXPKdvP1g== + dependencies: + buffer-crc32 "^0.2.5" + minimist "^1.2.0" + sander "^0.5.0" + sourcemap-codec "^1.3.0" + +source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== +source-map-resolve@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.6.0.tgz#3d9df87e236b53f16d01e58150fc7711138e5ed2" + integrity sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + source-map-support@0.5.13: version "0.5.13" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" @@ -4348,17 +4227,12 @@ source-map-support@0.5.13: buffer-from "^1.0.0" source-map "^0.6.0" -source-map@0.5.6: - version "0.5.6" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" - integrity sha1-dc449SvwczxafwwRjYEzSiu19BI= - source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -sourcemap-codec@^1.4.8: +sourcemap-codec@^1.3.0, sourcemap-codec@^1.4.8: version "1.4.8" resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== @@ -4366,7 +4240,7 @@ sourcemap-codec@^1.4.8: sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== sshpk@^1.14.1: version "1.17.0" @@ -4421,11 +4295,6 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= - strip-bom@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" @@ -4436,10 +4305,12 @@ strip-final-newline@^2.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== -strip-json-comments@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= +strip-indent@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" + integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ== + dependencies: + min-indent "^1.0.0" strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: version "3.1.1" @@ -4480,11 +4351,43 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== +svelte-hmr@^0.14.12: + version "0.14.12" + resolved "https://registry.yarnpkg.com/svelte-hmr/-/svelte-hmr-0.14.12.tgz#a127aec02f1896500b10148b2d4d21ddde39973f" + integrity sha512-4QSW/VvXuqVcFZ+RhxiR8/newmwOCTlbYIezvkeN6302YFRE8cXy0naamHcjz8Y9Ce3ITTZtrHrIL0AGfyo61w== + +svelte-jester@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/svelte-jester/-/svelte-jester-2.3.2.tgz#9eb818da30807bbcc940b6130d15b2c34408d64f" + integrity sha512-JtxSz4FWAaCRBXbPsh4LcDs4Ua7zdXgLC0TZvT1R56hRV0dymmNP+abw67DTPF7sQPyNxWsOKd0Sl7Q8SnP8kg== + +svelte-preprocess@^4.10.7: + version "4.10.7" + resolved "https://registry.yarnpkg.com/svelte-preprocess/-/svelte-preprocess-4.10.7.tgz#3626de472f51ffe20c9bc71eff5a3da66797c362" + integrity sha512-sNPBnqYD6FnmdBrUmBCaqS00RyCsCpj2BG58A1JBswNF7b0OKviwxqVrOL/CKyJrLSClrSeqQv5BXNg2RUbPOw== + dependencies: + "@types/pug" "^2.0.4" + "@types/sass" "^1.16.0" + detect-indent "^6.0.0" + magic-string "^0.25.7" + sorcery "^0.10.0" + strip-indent "^3.0.0" + +svelte@^3.48.0: + version "3.48.0" + resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.48.0.tgz#f98c866d45e155bad8e1e88f15f9c03cd28753d3" + integrity sha512-fN2YRm/bGumvjUpu6yI3BpvZnpIm9I6A7HR4oUNYd7ggYyIwSA/BX7DJ+UXXffLp6XNcUijyLvttbPVCYa/3xQ== + symbol-tree@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== +tabler-icons-svelte@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/tabler-icons-svelte/-/tabler-icons-svelte-1.8.0.tgz#c0b3305eeb75bc8044530622430e061ea3cb9153" + integrity sha512-j8VrSMsj8dwOTGNb4LldR0S+Dh+26D0tf5vJLPJ4v23V4xiL+SUIiyQyhzf7Pclx8Vd/x7WHsi9XsMVvteTNtg== + tailwindcss@^3.0.24: version "3.0.24" resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.0.24.tgz#22e31e801a44a78a1d9a81ecc52e13b69d85704d" @@ -4529,6 +4432,11 @@ test-exclude@^6.0.0: glob "^7.1.4" minimatch "^3.0.4" +test-jest@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/test-jest/-/test-jest-1.0.1.tgz#3f329be1a83d9037feb358b065ffc42ec9578e92" + integrity sha512-n3M1YTxgm/9X9OnlPSrFrCUkzWs7aSMjWVPNQxkx95KNBeZ8nXrDWsx9UvMQ8dcI9BFcOCABY2Inumh2TTmnvg== + text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -4616,16 +4524,6 @@ ts-jest@^28.0.4: semver "7.x" yargs-parser "^20.x" -tsconfig@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/tsconfig/-/tsconfig-7.0.0.tgz#84538875a4dc216e5c4a5432b3a4dec3d54e91b7" - integrity sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw== - dependencies: - "@types/strip-bom" "^3.0.0" - "@types/strip-json-comments" "0.0.30" - strip-bom "^3.0.0" - strip-json-comments "^2.0.0" - tslib@^1.8.1: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" @@ -4777,49 +4675,6 @@ vite@^2.9.10: optionalDependencies: fsevents "~2.3.2" -vue-demi@*: - version "0.13.1" - resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.13.1.tgz#7604904c88be338418a10abbc94d5b8caa14cb8c" - integrity sha512-xmkJ56koG3ptpLnpgmIzk9/4nFf4CqduSJbUM0OdPoU87NwRuZ6x49OLhjSa/fC15fV+5CbEnrxU4oyE022svg== - -vue-eslint-parser@^9.0.1: - version "9.0.2" - resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-9.0.2.tgz#d2535516f3f55adb387939427fe741065eb7948a" - integrity sha512-uCPQwTGjOtAYrwnU+76pYxalhjsh7iFBsHwBqDHiOPTxtICDaraO4Szw54WFTNZTAEsgHHzqFOu1mmnBOBRzDA== - 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" - -vue-router@^4.0.15: - version "4.0.15" - resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-4.0.15.tgz#b4a0661efe197f8c724e0f233308f8776e2c3667" - integrity sha512-xa+pIN9ZqORdIW1MkN2+d9Ui2pCM1b/UMgwYUCZOiFYHAvz/slKKBDha8DLrh5aCG/RibtrpyhKjKOZ85tYyWg== - dependencies: - "@vue/devtools-api" "^6.0.0" - -vue-tsc@^0.37.3: - version "0.37.3" - resolved "https://registry.yarnpkg.com/vue-tsc/-/vue-tsc-0.37.3.tgz#1a7858fd810c498876bb6e315c40cae9c1aca6bc" - integrity sha512-MB8aU+9z722Q1tD/pg8ZKnkOSZI1yAlPYCA7R42B86XCUJ/w7fQtlI8Ojcgznz7IH3SxIkOVIw+S6TfddOa9gg== - dependencies: - "@volar/vue-typescript" "0.37.3" - -vue@^3.2.37: - version "3.2.37" - resolved "https://registry.yarnpkg.com/vue/-/vue-3.2.37.tgz#da220ccb618d78579d25b06c7c21498ca4e5452e" - integrity sha512-bOKEZxrm8Eh+fveCqS1/NkG/n6aMidsI6hahas7pa0w/l7jkbssJVsRhVDs07IdDq7h9KHswZOgItnwJAgtVtQ== - dependencies: - "@vue/compiler-dom" "3.2.37" - "@vue/compiler-sfc" "3.2.37" - "@vue/runtime-dom" "3.2.37" - "@vue/server-renderer" "3.2.37" - "@vue/shared" "3.2.37" - w3c-hr-time@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" @@ -4942,11 +4797,6 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= - yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"