diff --git a/.gitignore b/.gitignore index d6c6d41e3ca..9dd73547646 100644 --- a/.gitignore +++ b/.gitignore @@ -106,3 +106,10 @@ tags.lock tags.temp .stylelintcache .solargraph.yml + +# Vite Ruby +/public/vite* +# Vite uses dotenv and suggests to ignore local-only env files. See +# https://vitejs.dev/guide/env-and-mode.html#env-files +*.local + diff --git a/.gitlab/ci/frontend.gitlab-ci.yml b/.gitlab/ci/frontend.gitlab-ci.yml index f103032ee69..1f1065a9830 100644 --- a/.gitlab/ci/frontend.gitlab-ci.yml +++ b/.gitlab/ci/frontend.gitlab-ci.yml @@ -11,6 +11,7 @@ # https://github.com/browserslist/browserslist/blob/a287ec6/node.js#L367-L384 BROWSERSLIST_IGNORE_OLD_DATA: "true" WEBPACK_COMPILE_LOG_PATH: "tmp/webpack-output.log" + VITE_RUBY_SKIP_ASSETS_PRECOMPILE_EXTENSION: "true" stage: prepare needs: [] script: diff --git a/Gemfile b/Gemfile index e95dba4cb1b..f55eac0f475 100644 --- a/Gemfile +++ b/Gemfile @@ -19,6 +19,8 @@ gem 'rails', '~> 7.0.6' gem 'activerecord-gitlab', path: 'gems/activerecord-gitlab' +gem 'vite_rails' + gem 'bootsnap', '~> 1.16.0', require: false gem 'openssl', '~> 3.0' diff --git a/Gemfile.checksum b/Gemfile.checksum index e7d34d6f626..748633e2fcc 100644 --- a/Gemfile.checksum +++ b/Gemfile.checksum @@ -125,6 +125,7 @@ {"name":"doorkeeper","version":"5.6.6","platform":"ruby","checksum":"2344e86c77770526efcda893b5217aa13d1c7eb1b40de840b58b19eb1ff757e0"}, {"name":"doorkeeper-openid_connect","version":"1.8.7","platform":"ruby","checksum":"71edaf33118deefe25674ba3f8280c32835f057351f70e9beb222c0fd6b8e786"}, {"name":"dotenv","version":"2.7.6","platform":"ruby","checksum":"2451ed5e8e43776d7a787e51d6f8903b98e446146c7ad143d5678cc2c409d547"}, +{"name":"dry-cli","version":"1.0.0","platform":"ruby","checksum":"28ead169f872954dd08910eb8ead59cf86cd18b4aab321e8eeefe945749569f0"}, {"name":"dry-core","version":"1.0.0","platform":"ruby","checksum":"7a92099870967f0d2c9997950608cb8bb622dafeea20b2fe1dd49e9ba1d0f305"}, {"name":"dry-inflector","version":"1.0.0","platform":"ruby","checksum":"6ad22361ca2d6f3f001ae3037ffcfea01163f644280d13a9195d3c3a94dd1626"}, {"name":"dry-logic","version":"1.5.0","platform":"ruby","checksum":"99ed2180f1970c3d8247004f277a01dffbe8e82cf6680de9c7209312d86cd416"}, @@ -675,6 +676,8 @@ {"name":"version_sorter","version":"2.3.0","platform":"ruby","checksum":"2147f2a1a3804fbb8f60d268b7d7c1ec717e6dd727ffe2c165b4e05e82efe1da"}, {"name":"view_component","version":"3.2.0","platform":"ruby","checksum":"1dfaa85e13b5393f30b60bd3a03348b5298240a13137985d71eb2b8cc94c4c22"}, {"name":"virtus","version":"2.0.0","platform":"ruby","checksum":"8841dae4eb7fcc097320ba5ea516bf1839e5d056c61ee27138aa4bddd6e3d1c2"}, +{"name":"vite_rails","version":"3.0.15","platform":"ruby","checksum":"b8ec528aedf7e24b54f222b449cd9250810ea2456d5f8dd4ef87f06b475cf860"}, +{"name":"vite_ruby","version":"3.3.4","platform":"ruby","checksum":"025e438385a6dc2320c8c148dff453f5bb1d4f056ce69c3386f47d4c388ad80c"}, {"name":"vmstat","version":"2.3.0","platform":"ruby","checksum":"ab5446a3e3bd0a9cdb9d9ac69a0bbd119c4f161d945a0846a519dd7018af656d"}, {"name":"warden","version":"1.2.9","platform":"ruby","checksum":"46684f885d35a69dbb883deabf85a222c8e427a957804719e143005df7a1efd0"}, {"name":"warning","version":"1.3.0","platform":"ruby","checksum":"23695a5d8e50bd5c46068931b529bee0b28e4982cbcefbe77d867800dde8069e"}, diff --git a/Gemfile.lock b/Gemfile.lock index 824dadab308..7f2f8307779 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -459,6 +459,7 @@ GEM doorkeeper (>= 5.5, < 5.7) jwt (>= 2.5) dotenv (2.7.6) + dry-cli (1.0.0) dry-core (1.0.0) concurrent-ruby (~> 1.0) zeitwerk (~> 2.6) @@ -1672,6 +1673,13 @@ GEM axiom-types (~> 0.1) coercible (~> 1.0) descendants_tracker (~> 0.0, >= 0.0.3) + vite_rails (3.0.15) + railties (>= 5.1, < 8) + vite_ruby (~> 3.0, >= 3.2.2) + vite_ruby (3.3.4) + dry-cli (>= 0.7, < 2) + rack-proxy (~> 0.6, >= 0.6.1) + zeitwerk (~> 2.2) vmstat (2.3.0) warden (1.2.9) rack (>= 2.0.9) @@ -2029,6 +2037,7 @@ DEPENDENCIES validates_hostname (~> 1.0.11) version_sorter (~> 2.3) view_component (~> 3.2.0) + vite_rails vmstat (~> 2.3.0) warning (~> 1.3.0) webauthn (~> 3.0) diff --git a/app/assets/javascripts/diffs/components/diff_content.vue b/app/assets/javascripts/diffs/components/diff_content.vue index 1c93cb4d021..11ae9d79def 100644 --- a/app/assets/javascripts/diffs/components/diff_content.vue +++ b/app/assets/javascripts/diffs/components/diff_content.vue @@ -3,7 +3,7 @@ import { GlLoadingIcon, GlButton } from '@gitlab/ui'; import { mapActions, mapGetters, mapState } from 'vuex'; import { sprintf } from '~/locale'; import { createAlert } from '~/alert'; -import { mapParallel, mapParallelNoSast } from 'ee_else_ce/diffs/components/diff_row_utils'; +import { mapParallel } from 'ee_else_ce/diffs/components/diff_row_utils'; import DiffFileDrafts from '~/batch_comments/components/diff_file_drafts.vue'; import draftCommentsMixin from '~/diffs/mixins/draft_comments'; import { diffViewerModes } from '~/ide/constants'; @@ -14,7 +14,6 @@ import NotDiffableViewer from '~/vue_shared/components/diff_viewer/viewers/not_d import NoteForm from '~/notes/components/note_form.vue'; import eventHub from '~/notes/event_hub'; import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue'; -import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import { IMAGE_DIFF_POSITION_TYPE } from '../constants'; import { SAVING_THE_COMMENT_FAILED, SOMETHING_WENT_WRONG } from '../i18n'; import { getDiffMode } from '../store/utils'; @@ -36,7 +35,7 @@ export default { UserAvatarLink, DiffFileDrafts, }, - mixins: [diffLineNoteFormMixin, draftCommentsMixin, glFeatureFlagsMixin()], + mixins: [diffLineNoteFormMixin, draftCommentsMixin], props: { diffFile: { type: Object, @@ -92,11 +91,7 @@ export default { return this.getUserData; }, mappedLines() { - if (this.glFeatures.sastReportsInInlineDiff) { - return this.diffLines(this.diffFile).map(mapParallel(this)) || []; - } - - return this.diffLines(this.diffFile).map(mapParallelNoSast(this)) || []; + return this.diffLines(this.diffFile).map(mapParallel(this)) || []; }, imageDiscussions() { return this.diffFile.discussions.filter( diff --git a/app/assets/javascripts/diffs/components/diff_line.vue b/app/assets/javascripts/diffs/components/diff_line.vue index fb201a558d4..4867a21493f 100644 --- a/app/assets/javascripts/diffs/components/diff_line.vue +++ b/app/assets/javascripts/diffs/components/diff_line.vue @@ -15,31 +15,18 @@ export default { parsedCodeQuality() { return (this.line.left ?? this.line.right)?.codequality; }, - parsedSast() { - return (this.line.left ?? this.line.right)?.sast; - }, codeQualityLineNumber() { return this.parsedCodeQuality[0]?.line; }, - sastLineNumber() { - return this.parsedSast[0]?.line; - }, }, methods: { hideInlineFindings() { - this.$emit( - 'hideInlineFindings', - this.codeQualityLineNumber ? this.codeQualityLineNumber : this.sastLineNumber, - ); + this.$emit('hideInlineFindings', this.codeQualityLineNumber); }, }, }; diff --git a/app/assets/javascripts/diffs/components/diff_row.vue b/app/assets/javascripts/diffs/components/diff_row.vue index 52a8cf29052..318ecc89d14 100644 --- a/app/assets/javascripts/diffs/components/diff_row.vue +++ b/app/assets/javascripts/diffs/components/diff_row.vue @@ -342,7 +342,6 @@ export default { v-if="$options.showCodequalityLeft(props) || $options.showSecurityLeft(props)" :inline-findings-expanded="props.inlineFindingsExpanded" :codequality="props.line.left.codequality" - :sast="props.line.left.sast" :file-path="props.filePath" @showInlineFindings=" listeners.toggleCodeQualityFindings( @@ -483,7 +482,6 @@ export default { :is="$options.InlineFindingsGutterIcon" v-if="$options.showCodequalityRight(props) || $options.showSecurityRight(props)" :codequality="props.line.right.codequality" - :sast="props.line.right.sast" :file-path="props.filePath" data-testid="inlineFindingsIcon" @showInlineFindings=" diff --git a/app/assets/javascripts/diffs/components/diff_row_utils.js b/app/assets/javascripts/diffs/components/diff_row_utils.js index 28834dab3b3..a489c96b0c9 100644 --- a/app/assets/javascripts/diffs/components/diff_row_utils.js +++ b/app/assets/javascripts/diffs/components/diff_row_utils.js @@ -189,7 +189,3 @@ export const mapParallel = (content) => (line) => { commentRowClasses: hasDiscussions(left) || hasDiscussions(right) ? '' : 'js-temp-notes-holder', }; }; - -export const mapParallelNoSast = (content) => { - return mapParallel(content); -}; diff --git a/app/assets/javascripts/diffs/components/diff_view.vue b/app/assets/javascripts/diffs/components/diff_view.vue index 09e3f36fa6f..3eacd42831f 100644 --- a/app/assets/javascripts/diffs/components/diff_view.vue +++ b/app/assets/javascripts/diffs/components/diff_view.vue @@ -4,6 +4,7 @@ import { throttle } from 'lodash'; import { IdState } from 'vendor/vue-virtual-scroller'; import DraftNote from '~/batch_comments/components/draft_note.vue'; import draftCommentsMixin from '~/diffs/mixins/draft_comments'; +import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import { getCommentedLines } from '~/notes/components/multiline_comment_utils'; import { hide } from '~/tooltips'; import { pickDirection } from '../utils/diff_line'; @@ -21,7 +22,11 @@ export default { DiffCommentCell, DraftNote, }, - mixins: [draftCommentsMixin, IdState({ idProp: (vm) => vm.diffFile.file_hash })], + mixins: [ + draftCommentsMixin, + IdState({ idProp: (vm) => vm.diffFile.file_hash }), + glFeatureFlagsMixin(), + ], props: { diffFile: { type: Object, @@ -44,7 +49,7 @@ export default { }, data() { return { - codeQualityExpandedLines: [], + inlineFindingsExpandedLines: [], }; }, idState() { @@ -75,12 +80,15 @@ export default { this.diffLines, ); }, - hasCodequalityChanges() { + hasInlineFindingsChanges() { return ( this.codequalityDiff?.files?.[this.diffFile.file_path]?.length > 0 || this.sastDiff?.added?.length > 0 ); }, + sastReportsInInlineDiff() { + return this.glFeatures.sastReportsInInlineDiff; + }, }, created() { this.onDragOverThrottled = throttle((line) => this.onDragOver(line), 100, { leading: true }); @@ -101,14 +109,14 @@ export default { this.idState.dragStart = line; }, hideInlineFindings(line) { - const index = this.codeQualityExpandedLines.indexOf(line); + const index = this.inlineFindingsExpandedLines.indexOf(line); if (index > -1) { - this.codeQualityExpandedLines.splice(index, 1); + this.inlineFindingsExpandedLines.splice(index, 1); } }, toggleCodeQualityFindings(line) { - if (!this.codeQualityExpandedLines.includes(line)) { - this.codeQualityExpandedLines.push(line); + if (!this.inlineFindingsExpandedLines.includes(line)) { + this.inlineFindingsExpandedLines.push(line); } else { this.hideInlineFindings(line); } @@ -207,7 +215,7 @@ export default {
+ @@ -33,12 +29,6 @@ export default { :findings="codeQuality" /> - - { + document + .querySelector('meta[name="controller-path"]') + .content.split('/') + .forEach((part, index, arr) => { + const path = `${prefix}${[...arr.slice(0, index), part].join('/')}/index.js`; + modules[path]?.(); + }); +}; diff --git a/app/assets/javascripts/webpack.js b/app/assets/javascripts/webpack.js index 1c6e632135d..ef82142289d 100644 --- a/app/assets/javascripts/webpack.js +++ b/app/assets/javascripts/webpack.js @@ -7,6 +7,7 @@ * e.g. the `window` scope, because it needs to be executed in the scope of webpack. */ -if (gon && gon.webpack_public_path) { +// eslint-disable-next-line camelcase +if (gon && gon.webpack_public_path && typeof __webpack_public_path__ !== 'undefined') { __webpack_public_path__ = gon.webpack_public_path; // eslint-disable-line camelcase } diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 08e4f4956df..cec4b9bbc12 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -115,6 +115,24 @@ class ApplicationController < ActionController::Base content_security_policy do |p| next if p.directives.blank? + + if Rails.env.development? && Feature.enabled?(:vite) + vite_host = ViteRuby.instance.config.host + vite_port = ViteRuby.instance.config.port + vite_origin = "#{vite_host}:#{vite_port}" + http_origin = "http://#{vite_origin}" + ws_origin = "ws://#{vite_origin}" + wss_origin = "wss://#{vite_origin}" + gitlab_ws_origin = Gitlab::Utils.append_path(Gitlab.config.gitlab.url, 'vite-dev/') + http_path = Gitlab::Utils.append_path(http_origin, 'vite-dev/') + + connect_sources = p.directives['connect-src'] + p.connect_src(*(Array.wrap(connect_sources) | [ws_origin, wss_origin, http_path])) + + worker_sources = p.directives['worker-src'] + p.worker_src(*(Array.wrap(worker_sources) | [gitlab_ws_origin, http_path])) + end + next unless Gitlab::CurrentSettings.snowplow_enabled? && !Gitlab::CurrentSettings.snowplow_collector_hostname.blank? default_connect_src = p.directives['connect-src'] || p.directives['default-src'] diff --git a/app/controllers/groups/application_controller.rb b/app/controllers/groups/application_controller.rb index 5440908aee7..59343ec8b08 100644 --- a/app/controllers/groups/application_controller.rb +++ b/app/controllers/groups/application_controller.rb @@ -37,18 +37,6 @@ class Groups::ApplicationController < ApplicationController end end - def authorize_admin_group_runners! - unless can?(current_user, :admin_group_runners, group) - render_404 - end - end - - def authorize_read_group_runners! - unless can?(current_user, :read_group_runners, group) - render_404 - end - end - def authorize_create_deploy_token! unless can?(current_user, :create_deploy_token, group) render_404 diff --git a/app/controllers/groups/runners_controller.rb b/app/controllers/groups/runners_controller.rb index 2dd0e36b65f..b3539da8429 100644 --- a/app/controllers/groups/runners_controller.rb +++ b/app/controllers/groups/runners_controller.rb @@ -49,7 +49,7 @@ class Groups::RunnersController < Groups::ApplicationController end def authorize_update_runner! - return if can?(current_user, :admin_group_runners, group) && can?(current_user, :update_runner, runner) + return if can?(current_user, :update_runner, runner) render_404 end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 2bf239979f7..9efb0c61f8b 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -485,6 +485,15 @@ module ApplicationHelper end end + def controller_full_path + action = case controller.action_name + when 'create' then 'new' + when 'update' then 'edit' + else controller.action_name + end + "#{controller.controller_path}/#{action}" + end + private def browser_id diff --git a/app/helpers/vite_helper.rb b/app/helpers/vite_helper.rb new file mode 100644 index 00000000000..4d1085a5169 --- /dev/null +++ b/app/helpers/vite_helper.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module ViteHelper + def universal_javascript_include_tag(*args) + if vite_enabled + vite_javascript_tag(*args) + else + javascript_include_tag(*args) + end + end + + def universal_asset_path(*args) + if vite_enabled + vite_asset_path(*args) + else + asset_path(*args) + end + end + + private + + def vite_enabled + Feature.enabled?(:vite) && !Rails.env.test? && vite_running + end + + def vite_running + ViteRuby.instance.dev_server_running? + end +end diff --git a/app/helpers/webpack_helper.rb b/app/helpers/webpack_helper.rb index ba3c232bec4..92874168798 100644 --- a/app/helpers/webpack_helper.rb +++ b/app/helpers/webpack_helper.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true module WebpackHelper + include ViteHelper + def prefetch_link_tag(source) href = asset_path(source) @@ -14,7 +16,11 @@ module WebpackHelper end def webpack_bundle_tag(bundle) - javascript_include_tag(*webpack_entrypoint_paths(bundle)) + if vite_running + vite_javascript_tag bundle + else + javascript_include_tag(*webpack_entrypoint_paths(bundle)) + end end def webpack_preload_asset_tag(asset, options = {}) @@ -32,6 +38,8 @@ module WebpackHelper end def webpack_controller_bundle_tags + return if Feature.enabled?(:vite) && !Rails.env.test? + chunks = [] action = case controller.action_name diff --git a/app/models/performance_monitoring/prometheus_dashboard.rb b/app/models/performance_monitoring/prometheus_dashboard.rb deleted file mode 100644 index 6fea3abf3d9..00000000000 --- a/app/models/performance_monitoring/prometheus_dashboard.rb +++ /dev/null @@ -1,78 +0,0 @@ -# frozen_string_literal: true - -module PerformanceMonitoring - class PrometheusDashboard - include ActiveModel::Model - - attr_accessor :dashboard, :panel_groups, :path, :environment, :priority, :templating, :links - - validates :dashboard, presence: true - validates :panel_groups, array_members: { member_class: PerformanceMonitoring::PrometheusPanelGroup } - - class << self - def from_json(json_content) - build_from_hash(json_content).tap(&:validate!) - end - - def find_for(project:, user:, path:, options: {}) - template = { path: path, environment: options[:environment] } - rsp = Gitlab::Metrics::Dashboard::Finder.find(project, user, options.merge(dashboard_path: path)) - - case rsp[:http_status] || rsp[:status] - when :success - new(template.merge(rsp[:dashboard] || {})) # when there is empty dashboard file returned rsp is still a success - when :unprocessable_entity - new(template) # validation error - else - nil # any other error - end - end - - private - - def build_from_hash(attributes) - return new unless attributes.is_a?(Hash) - - new( - dashboard: attributes['dashboard'], - panel_groups: initialize_children_collection(attributes['panel_groups']) - ) - end - - def initialize_children_collection(children) - return unless children.is_a?(Array) - - children.map { |group| PerformanceMonitoring::PrometheusPanelGroup.from_json(group) } - end - end - - def to_yaml - self.as_json(only: yaml_valid_attributes).to_yaml - end - - # This method is planned to be refactored as a part of https://gitlab.com/gitlab-org/gitlab/-/issues/219398 - # implementation. For new existing logic was reused to faster deliver MVC - def schema_validation_warnings - self.class.from_json(reload_schema) - [] - rescue Gitlab::Metrics::Dashboard::Errors::LayoutError => e - [e.message] - rescue ActiveModel::ValidationError => e - e.model.errors.map { |error| "#{error.attribute}: #{error.message}" } - end - - private - - # dashboard finder methods are somehow limited, #find includes checking if - # user is authorised to view selected dashboard, but modifies schema, which in some cases may - # cause false positives returned from validation, and #find_raw does not authorise users - def reload_schema - project = environment&.project - project.nil? ? self.as_json : Gitlab::Metrics::Dashboard::Finder.find_raw(project, dashboard_path: path) - end - - def yaml_valid_attributes - %w(panel_groups panels metrics group priority type title y_label weight id unit label query query_range dashboard) - end - end -end diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb index f166946db29..c50f74f2b35 100644 --- a/app/policies/group_policy.rb +++ b/app/policies/group_policy.rb @@ -231,7 +231,6 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy enable :read_usage_quotas enable :read_group_runners - enable :admin_group_runners enable :register_group_runners enable :create_runner diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml index 53ecad1b474..ccb8f3d388b 100644 --- a/app/views/layouts/_head.html.haml +++ b/app/views/layouts/_head.html.haml @@ -48,6 +48,16 @@ = webpack_bundle_tag 'legacy_sentry' = webpack_bundle_tag 'performance_bar' if performance_bar_enabled? + - if vite_enabled + %meta{ name: 'controller-path', content: controller_full_path } + - if Rails.env.development? + = vite_client_tag + = vite_javascript_tag "main" + - if Gitlab.ee? + = vite_javascript_tag "main_ee" + - if Gitlab.jh? + = vite_javascript_tag "main_jh" + = yield :page_specific_javascripts = webpack_bundle_tag 'super_sidebar' if show_super_sidebar? diff --git a/app/views/projects/runners/_group_runners.html.haml b/app/views/projects/runners/_group_runners.html.haml index 32a2e36c779..2d435a7ce9d 100644 --- a/app/views/projects/runners/_group_runners.html.haml +++ b/app/views/projects/runners/_group_runners.html.haml @@ -27,7 +27,7 @@ - elsif @group_runners.empty? = _('This group does not have any group runners yet.') - - if can?(current_user, :admin_group_runners, @project.group) + - if can?(current_user, :register_group_runners, @project.group) || can?(current_user, :create_runner, @project.group) - group_link_start = "".html_safe - group_link_end = ''.html_safe = s_("Runners|To register them, go to the %{link_start}group's Runners page%{link_end}.").html_safe % { link_start: group_link_start, link_end: group_link_end } diff --git a/bin/vite b/bin/vite new file mode 100755 index 00000000000..7527d097eb6 --- /dev/null +++ b/bin/vite @@ -0,0 +1,27 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +# +# This file was generated by Bundler. +# +# The application 'vite' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) + +bundle_binstub = File.expand_path("bundle", __dir__) + +if File.file?(bundle_binstub) + if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/ + load(bundle_binstub) + else + abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. +Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") + end +end + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("vite_ruby", "vite") diff --git a/config/feature_flags/development/lfs_batch_direct_downloads.yml b/config/feature_flags/development/lfs_batch_direct_downloads.yml index 3d16a54a16d..33fe2a55b23 100644 --- a/config/feature_flags/development/lfs_batch_direct_downloads.yml +++ b/config/feature_flags/development/lfs_batch_direct_downloads.yml @@ -1,8 +1,8 @@ --- name: lfs_batch_direct_downloads introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/122221 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/413684 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/421692 milestone: '16.1' type: development -group: group::tenant scale +group: group::source code default_enabled: true diff --git a/config/feature_flags/development/vite.yml b/config/feature_flags/development/vite.yml new file mode 100644 index 00000000000..49a5e4c8a79 --- /dev/null +++ b/config/feature_flags/development/vite.yml @@ -0,0 +1,8 @@ +--- +name: vite +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/94685 +rollout_issue_url: +milestone: '16.0' +type: development +group: group::foundations +default_enabled: false diff --git a/config/vite.json b/config/vite.json new file mode 100644 index 00000000000..b428b0daec0 --- /dev/null +++ b/config/vite.json @@ -0,0 +1,18 @@ +{ + "all": { + "sourceCodeDir": "app/assets", + "entrypointsDir": "javascripts/entrypoints", + "devServerConnectTimeout": 3 + }, + "development": { + "autoBuild": true, + "publicOutputDir": "vite-dev", + "host": "localhost", + "port": 3038 + }, + "test": { + "autoBuild": true, + "publicOutputDir": "vite-test", + "port": 3037 + } +} diff --git a/config/webpack.config.js b/config/webpack.config.js index a4d2d188227..08b28fea47b 100644 --- a/config/webpack.config.js +++ b/config/webpack.config.js @@ -18,8 +18,6 @@ const fs = require('fs'); const path = require('path'); const BABEL_VERSION = require('@babel/core/package.json').version; -const SOURCEGRAPH_VERSION = require('@sourcegraph/code-host-integration/package.json').version; -const GITLAB_WEB_IDE_VERSION = require('@gitlab/web-ide/package.json').version; const BABEL_LOADER_VERSION = require('babel-loader/package.json').version; const CompressionPlugin = require('compression-webpack-plugin'); @@ -37,14 +35,23 @@ const { StatsWriterPlugin } = require('webpack-stats-plugin'); const WEBPACK_VERSION = require('webpack/package.json').version; const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin'); +const { + IS_EE, + IS_JH, + ROOT_PATH, + WEBPACK_OUTPUT_PATH, + WEBPACK_PUBLIC_PATH, + SOURCEGRAPH_PUBLIC_PATH, + SOURCEGRAPH_OUTPUT_PATH, + GITLAB_WEB_IDE_OUTPUT_PATH, + GITLAB_WEB_IDE_PUBLIC_PATH, +} = require('./webpack.constants'); + const createIncrementalWebpackCompiler = require('./helpers/incremental_webpack_compiler'); -const IS_EE = require('./helpers/is_ee_env'); -const IS_JH = require('./helpers/is_jh_env'); const vendorDllHash = require('./helpers/vendor_dll_hash'); const GraphqlKnownOperationsPlugin = require('./plugins/graphql_known_operations_plugin'); -const ROOT_PATH = path.resolve(__dirname, '..'); const SUPPORTED_BROWSERS = fs.readFileSync(path.join(ROOT_PATH, '.browserslistrc'), 'utf-8'); const SUPPORTED_BROWSERS_HASH = crypto .createHash('sha256') @@ -82,19 +89,9 @@ if (WEBPACK_REPORT) { NO_HASHED_CHUNKS = true; } -const WEBPACK_OUTPUT_PATH = path.join(ROOT_PATH, 'public/assets/webpack'); -const WEBPACK_PUBLIC_PATH = '/assets/webpack/'; const SOURCEGRAPH_PACKAGE = '@sourcegraph/code-host-integration'; const GITLAB_WEB_IDE_PACKAGE = '@gitlab/web-ide'; -const SOURCEGRAPH_PATH = path.join('sourcegraph', SOURCEGRAPH_VERSION, '/'); -const SOURCEGRAPH_OUTPUT_PATH = path.join(WEBPACK_OUTPUT_PATH, SOURCEGRAPH_PATH); -const SOURCEGRAPH_PUBLIC_PATH = path.join(WEBPACK_PUBLIC_PATH, SOURCEGRAPH_PATH); - -const GITLAB_WEB_IDE_PATH = path.join('gitlab-vscode', GITLAB_WEB_IDE_VERSION, '/'); -const GITLAB_WEB_IDE_OUTPUT_PATH = path.join(WEBPACK_OUTPUT_PATH, GITLAB_WEB_IDE_PATH); -const GITLAB_WEB_IDE_PUBLIC_PATH = path.join(WEBPACK_PUBLIC_PATH, GITLAB_WEB_IDE_PATH); - const devtool = IS_PRODUCTION ? 'source-map' : 'cheap-module-eval-source-map'; let autoEntriesCount = 0; diff --git a/config/webpack.constants.js b/config/webpack.constants.js new file mode 100644 index 00000000000..0eb2ac70c82 --- /dev/null +++ b/config/webpack.constants.js @@ -0,0 +1,31 @@ +const path = require('path'); + +const ROOT_PATH = path.resolve(__dirname, '..'); +const WEBPACK_OUTPUT_PATH = path.join(ROOT_PATH, 'public/assets/webpack'); +const WEBPACK_PUBLIC_PATH = '/assets/webpack/'; +const SOURCEGRAPH_VERSION = require('@sourcegraph/code-host-integration/package.json').version; + +const SOURCEGRAPH_PATH = path.join('sourcegraph', SOURCEGRAPH_VERSION, '/'); +const SOURCEGRAPH_OUTPUT_PATH = path.join(WEBPACK_OUTPUT_PATH, SOURCEGRAPH_PATH); +const SOURCEGRAPH_PUBLIC_PATH = path.join(WEBPACK_PUBLIC_PATH, SOURCEGRAPH_PATH); + +const GITLAB_WEB_IDE_VERSION = require('@gitlab/web-ide/package.json').version; + +const GITLAB_WEB_IDE_PATH = path.join('gitlab-vscode', GITLAB_WEB_IDE_VERSION, '/'); +const GITLAB_WEB_IDE_OUTPUT_PATH = path.join(WEBPACK_OUTPUT_PATH, GITLAB_WEB_IDE_PATH); +const GITLAB_WEB_IDE_PUBLIC_PATH = path.join(WEBPACK_PUBLIC_PATH, GITLAB_WEB_IDE_PATH); + +const IS_EE = require('./helpers/is_ee_env'); +const IS_JH = require('./helpers/is_jh_env'); + +module.exports = { + IS_EE, + IS_JH, + ROOT_PATH, + WEBPACK_OUTPUT_PATH, + WEBPACK_PUBLIC_PATH, + SOURCEGRAPH_OUTPUT_PATH, + SOURCEGRAPH_PUBLIC_PATH, + GITLAB_WEB_IDE_OUTPUT_PATH, + GITLAB_WEB_IDE_PUBLIC_PATH, +}; diff --git a/db/post_migrate/20230726024322_add_not_valid_foreign_key_for_ci_pipeline_variables_pipeline_id.rb b/db/post_migrate/20230726024322_add_not_valid_foreign_key_for_ci_pipeline_variables_pipeline_id.rb new file mode 100644 index 00000000000..f9785aca1ae --- /dev/null +++ b/db/post_migrate/20230726024322_add_not_valid_foreign_key_for_ci_pipeline_variables_pipeline_id.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +class AddNotValidForeignKeyForCiPipelineVariablesPipelineId < Gitlab::Database::Migration[2.1] + disable_ddl_transaction! + + SOURCE_TABLE = :ci_pipeline_variables + TARGET_TABLE = :ci_pipelines + COLUMN_NAME = :pipeline_id_convert_to_bigint + FK_NAME = 'temp_fk_rails_8d3b04e3e1' + + def up + add_concurrent_foreign_key( + SOURCE_TABLE, TARGET_TABLE, + name: FK_NAME, + column: COLUMN_NAME, + on_delete: :cascade, + validate: false, + reverse_lock_order: true + ) + + prepare_async_foreign_key_validation SOURCE_TABLE, name: FK_NAME + end + + def down + unprepare_async_foreign_key_validation SOURCE_TABLE, name: FK_NAME + + remove_foreign_key_if_exists SOURCE_TABLE, name: FK_NAME + end +end diff --git a/db/schema_migrations/20230726024322 b/db/schema_migrations/20230726024322 new file mode 100644 index 00000000000..07cf70cbd6f --- /dev/null +++ b/db/schema_migrations/20230726024322 @@ -0,0 +1 @@ +29394a35335d42c959b5f8566e26787d6029e7d7a12706cc09d61129536eedcb \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 3200a7ca4dc..95404b79265 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -38710,6 +38710,9 @@ ALTER TABLE issue_search_data ALTER TABLE product_analytics_events_experimental ADD CONSTRAINT product_analytics_events_experimental_project_id_fkey FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE; +ALTER TABLE ONLY ci_pipeline_variables + ADD CONSTRAINT temp_fk_rails_8d3b04e3e1 FOREIGN KEY (pipeline_id_convert_to_bigint) REFERENCES ci_pipelines(id) ON DELETE CASCADE NOT VALID; + ALTER TABLE ONLY user_follow_users ADD CONSTRAINT user_follow_users_followee_id_fkey FOREIGN KEY (followee_id) REFERENCES users(id) ON DELETE CASCADE; diff --git a/doc/administration/operations/rails_console.md b/doc/administration/operations/rails_console.md index ac0a7e5870b..b3e7a97428a 100644 --- a/doc/administration/operations/rails_console.md +++ b/doc/administration/operations/rails_console.md @@ -508,7 +508,7 @@ def disable_two_factor! otp_grace_period_started_at: nil, otp_backup_codes: nil ) - self.u2f_registrations.destroy_all # rubocop: disable DestroyAll + self.webauthn_registrations.destroy_all # rubocop: disable DestroyAll end end diff --git a/doc/api/group_access_tokens.md b/doc/api/group_access_tokens.md index 2493dfcc039..4904785c2f0 100644 --- a/doc/api/group_access_tokens.md +++ b/doc/api/group_access_tokens.md @@ -152,6 +152,11 @@ curl --request POST --header "PRIVATE-TOKEN: " "https://gitla - Token with the specified ID does not exist. - `404: Not Found` if the user is an administrator but the token with the specified ID does not exist. +### Automatic reuse detection + +Refer to [automatic reuse detection for personal access tokens](personal_access_tokens.md#automatic-reuse-detection) +for more information. + ## Revoke a group access token > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77236) in GitLab 14.7. diff --git a/doc/api/personal_access_tokens.md b/doc/api/personal_access_tokens.md index 691c094f9eb..49766bd9e68 100644 --- a/doc/api/personal_access_tokens.md +++ b/doc/api/personal_access_tokens.md @@ -235,6 +235,21 @@ curl --request POST --header "PRIVATE-TOKEN: " "https://gitla - Token with the specified ID does not exist. - `404: Not Found` if the user is an administrator but the token with the specified ID does not exist. +### Automatic reuse detection + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/395352) in GitLab 16.3 + +For each rotated token, the previous and now revoked token is referenced. This +chain of references defines a token family. In a token family, only the latest +token is active, and all other tokens in that family are revoked. + +When a revoked token from a token family is used in an authentication attempt, +that attempt fails and the active token from the token family gets revoked. +This mechanism helps to prevent compromise when a personal access token is +leaked. + +Automatic reuse detection is enabled for API requests. + ## Revoke a personal access token Revoke a personal access token by either: diff --git a/doc/api/project_access_tokens.md b/doc/api/project_access_tokens.md index 36129bf6576..5cb4276fa1d 100644 --- a/doc/api/project_access_tokens.md +++ b/doc/api/project_access_tokens.md @@ -161,6 +161,11 @@ curl --request POST --header "PRIVATE-TOKEN: " "https://gitla - Token with the specified ID does not exist. - `404: Not Found` if the user is an administrator but the token with the specified ID does not exist. +### Automatic reuse detection + +Refer to [automatic reuse detection for personal access tokens](personal_access_tokens.md#automatic-reuse-detection) +for more information. + ## Revoke a project access token > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/238991) in GitLab 13.9. diff --git a/doc/ci/pipelines/cicd_minutes.md b/doc/ci/pipelines/cicd_minutes.md index 84f59089ad2..d73a432fe85 100644 --- a/doc/ci/pipelines/cicd_minutes.md +++ b/doc/ci/pipelines/cicd_minutes.md @@ -269,8 +269,9 @@ GitLab SaaS runners have different cost factors, depending on the runner type (L | Linux OS amd64 | small | 1 | | Linux OS amd64 | medium | 2 | | Linux OS amd64 | large | 3 | +| Linux OS amd64 | xlarge | 6 | | Linux OS amd64 + GPU-enabled | medium, GPU standard | 7 | -| macOS M1 | Medium | 6 | +| macOS M1 | medium | 6 (Beta) | | Windows Server | - | 1 (Beta) | ### Monthly reset of compute usage diff --git a/doc/ci/runners/saas/linux_saas_runner.md b/doc/ci/runners/saas/linux_saas_runner.md index 0596c322863..c3f043dedcd 100644 --- a/doc/ci/runners/saas/linux_saas_runner.md +++ b/doc/ci/runners/saas/linux_saas_runner.md @@ -21,7 +21,8 @@ For Free, Premium, and Ultimate plan customers, jobs on these instances consume |----------------------------------------------|-------|--------|---------| | `saas-linux-small-amd64` | 2 | 8 GB | 25 GB | | `saas-linux-medium-amd64` | 4 | 16 GB | 50 GB | -| `saas-linux-large-amd64` **(PREMIUM SAAS)** | 8 | 32 GB | 100 GB | +| `saas-linux-large-amd64` **(PREMIUM SAAS)** | 8 | 32 GB | 100 GB | +| `saas-linux-xlarge-amd64` **(PREMIUM SAAS)** | 16 | 64 GB | 200 GB | The `small` machine type is set as default. If no [tag](../../yaml/index.md#tags) keyword in your `.gitlab-ci.yml` file is specified, the jobs will run on this default runner. diff --git a/lib/backup/gitaly_backup.rb b/lib/backup/gitaly_backup.rb index bb9f45121e9..5b55c2cbdf7 100644 --- a/lib/backup/gitaly_backup.rb +++ b/lib/backup/gitaly_backup.rb @@ -10,11 +10,13 @@ module Backup # @param [Integer] max_parallelism max parallelism when running backups # @param [Integer] storage_parallelism max parallelism per storage (is affected by max_parallelism) # @param [Boolean] incremental if incremental backups should be created. - def initialize(progress, max_parallelism: nil, storage_parallelism: nil, incremental: false) + # @param [Boolean] server_side if server-side backups should be used. + def initialize(progress, max_parallelism: nil, storage_parallelism: nil, incremental: false, server_side: false) @progress = progress @max_parallelism = max_parallelism @storage_parallelism = storage_parallelism @incremental = incremental + @server_side = server_side end def start(type, backup_repos_path, backup_id: nil, remove_all_repositories: nil) @@ -24,28 +26,11 @@ module Backup FileUtils.rm_rf(backup_repos_path) end - command = case type - when :create - 'create' - when :restore - 'restore' - else - raise Error, "unknown backup type: #{type}" - end - - args = ['-layout', 'pointer'] - args += ['-parallel', @max_parallelism.to_s] if @max_parallelism - args += ['-parallel-storage', @storage_parallelism.to_s] if @storage_parallelism - - case type - when :create - args += ['-incremental'] if incremental? - args += ['-id', backup_id] if backup_id - when :restore - args += ['-remove-all-repositories', remove_all_repositories.join(',')] if remove_all_repositories - end - - @input_stream, stdout, @thread = Open3.popen2(build_env, bin_path, command, '-path', backup_repos_path, *args) + @input_stream, stdout, @thread = Open3.popen2( + build_env, + bin_path, + *gitaly_backup_args(type, backup_repos_path, backup_id, remove_all_repositories) + ) @out_reader = Thread.new do IO.copy_stream(stdout, @progress) @@ -78,6 +63,41 @@ module Backup @incremental end + def server_side? + @server_side + end + + def gitaly_backup_args(type, backup_repos_path, backup_id, remove_all_repositories) + command = case type + when :create + 'create' + when :restore + 'restore' + else + raise Error, "unknown backup type: #{type}" + end + + args = [command] + if server_side? + ['-server-side'] + else + ['-path', backup_repos_path, '-layout', 'pointer'] + end + + args += ['-parallel', @max_parallelism.to_s] if @max_parallelism + args += ['-parallel-storage', @storage_parallelism.to_s] if @storage_parallelism + + case type + when :create + args += ['-incremental'] if incremental? + args += ['-id', backup_id] if backup_id + when :restore + args += ['-remove-all-repositories', remove_all_repositories.join(',')] if remove_all_repositories + args += ['-id', backup_id] if backup_id && server_side? + end + + args + end + # Schedule a new backup job through a non-blocking JSON based pipe protocol # # @see https://gitlab.com/gitlab-org/gitaly/-/blob/master/doc/gitaly-backup.md diff --git a/lib/backup/manager.rb b/lib/backup/manager.rb index d56f852b23c..60239781926 100644 --- a/lib/backup/manager.rb +++ b/lib/backup/manager.rb @@ -195,7 +195,12 @@ module Backup def build_repositories_task max_concurrency = ENV['GITLAB_BACKUP_MAX_CONCURRENCY'].presence&.to_i max_storage_concurrency = ENV['GITLAB_BACKUP_MAX_STORAGE_CONCURRENCY'].presence&.to_i - strategy = Backup::GitalyBackup.new(progress, incremental: incremental?, max_parallelism: max_concurrency, storage_parallelism: max_storage_concurrency) + strategy = Backup::GitalyBackup.new(progress, + incremental: incremental?, + max_parallelism: max_concurrency, + storage_parallelism: max_storage_concurrency, + server_side: backup_information[:repositories_server_side] + ) Repositories.new(progress, strategy: strategy, @@ -286,7 +291,8 @@ module Backup skipped: ENV['SKIP'], repositories_storages: ENV['REPOSITORIES_STORAGES'], repositories_paths: ENV['REPOSITORIES_PATHS'], - skip_repositories_paths: ENV['SKIP_REPOSITORIES_PATHS'] + skip_repositories_paths: ENV['SKIP_REPOSITORIES_PATHS'], + repositories_server_side: Gitlab::Utils.to_boolean(ENV['REPOSITORIES_SERVER_SIDE'], default: false) } end diff --git a/lib/gitlab/metrics/dashboard/finder.rb b/lib/gitlab/metrics/dashboard/finder.rb deleted file mode 100644 index 7c21bb9cdcb..00000000000 --- a/lib/gitlab/metrics/dashboard/finder.rb +++ /dev/null @@ -1,86 +0,0 @@ -# frozen_string_literal: true - -# Returns DB-supplmented dashboard info for determining -# the layout of UI. Intended entry-point for the Metrics::Dashboard -# module. -module Gitlab - module Metrics - module Dashboard - class Finder - PREDEFINED_DASHBOARD_LIST = [ - ::Metrics::Dashboard::SystemDashboardService - ].freeze - - class << self - # Returns a formatted dashboard packed with DB info. - # @param project [Project] - # @param user [User] - # @param environment [Environment] - # @param options [Hash] - # @param options - embedded [Boolean] Determines whether the - # dashboard is to be rendered as part of an - # issue or location other than the primary - # metrics dashboard UI. Returns only the - # Memory/CPU charts of the system dash. - # @param options - dashboard_path [String] Path at which the - # dashboard can be found. Nil values will - # default to the system dashboard. - # @param options - group [String, Group] Title of the group - # to which a panel might belong. Used by - # embedded dashboards. If cluster dashboard, - # refers to the Group corresponding to the cluster. - # @param options - title [String] Title of the panel. - # Used by embedded dashboards. - # @param options - y_label [String] Y-Axis label of - # a panel. Used by embedded dashboards. - # @param options - cluster [Cluster]. Used by - # embedded and un-embedded dashboards. - # @param options - cluster_type [Symbol] The level of - # cluster, one of [:admin, :project, :group]. Used by - # embedded and un-embedded dashboards. - # @param options - grafana_url [String] URL pointing - # to a grafana dashboard panel - # @param options - prometheus_alert_id [Integer] ID of - # a PrometheusAlert. For dashboard embeds. - # @return [Hash] - def find(project, user, options = {}) - service_for(options) - .new(project, user, options) - .get_dashboard - end - - # Returns a dashboard without any supplemental info. - # Returns only full, yml-defined dashboards. - # @return [Hash] - def find_raw(project, dashboard_path: nil) - service_for(dashboard_path: dashboard_path) - .new(project, nil, dashboard_path: dashboard_path) - .raw_dashboard - end - - # Summary of all known dashboards. - # @return [Array] ex) [{ path: String, - # display_name: String, - # default: Boolean }] - def find_all_paths(project) - dashboards = PREDEFINED_DASHBOARD_LIST.flat_map do |service| - service.all_dashboard_paths(project) - end - - Gitlab::Utils.stable_sort_by(dashboards) { |dashboard| dashboard[:display_name].downcase } - end - - private - - def system_service - ::Metrics::Dashboard::SystemDashboardService - end - - def service_for(options) - Gitlab::Metrics::Dashboard::ServiceSelector.call(options) - end - end - end - end - end -end diff --git a/lib/gitlab/metrics/dashboard/service_selector.rb b/lib/gitlab/metrics/dashboard/service_selector.rb deleted file mode 100644 index 76ff00f86d8..00000000000 --- a/lib/gitlab/metrics/dashboard/service_selector.rb +++ /dev/null @@ -1,44 +0,0 @@ -# frozen_string_literal: true - -# Responsible for determining which dashboard service should -# be used to fetch or generate a dashboard hash. -# The services can be considered in two categories - embeds -# and dashboards. Embed hashes are identical to dashboard hashes except -# that they contain a subset of panels. -module Gitlab - module Metrics - module Dashboard - class ServiceSelector - class << self - include Gitlab::Utils::StrongMemoize - - SERVICES = [ - ::Metrics::Dashboard::SystemDashboardService - ].freeze - - # Returns a class which inherits from the BaseService - # class that can be used to obtain a dashboard for - # the provided params. - # @return [Metrics::Dashboard::BaseService] - def call(params) - service = services.find do |service_class| - service_class.valid_params?(params) - end - - service || default_service - end - - private - - def services - SERVICES - end - - def default_service - ::Metrics::Dashboard::SystemDashboardService - end - end - end - end - end -end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 3c93808323d..dc6b70ccc0d 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -1543,11 +1543,6 @@ msgid_plural "%d Issues" msgstr[0] "" msgstr[1] "" -msgid "1 Security finding" -msgid_plural "%d Security findings" -msgstr[0] "" -msgstr[1] "" - msgid "1 closed issue" msgid_plural "%{issues} closed issues" msgstr[0] "" @@ -52064,6 +52059,9 @@ msgstr "" msgid "VulnerabilityStatusTypes|Resolved" msgstr "" +msgid "Vulnerability|%{file} was not found in commit %{ref}" +msgstr "" + msgid "Vulnerability|%{scannerName} (version %{scannerVersion})" msgstr "" @@ -52265,6 +52263,9 @@ msgstr "" msgid "Vulnerability|Show prompt" msgstr "" +msgid "Vulnerability|Something went wrong while trying to get the source file." +msgstr "" + msgid "Vulnerability|Stacktrace snippet:" msgstr "" diff --git a/package.json b/package.json index 1bf2e454476..fbf2acaba41 100644 --- a/package.json +++ b/package.json @@ -234,8 +234,11 @@ "@gitlab/eslint-plugin": "19.0.0", "@gitlab/stylelint-config": "4.1.0", "@graphql-eslint/eslint-plugin": "3.20.1", + "@originjs/vite-plugin-commonjs": "^1.0.3", + "@rollup/plugin-graphql": "^2.0.3", "@testing-library/dom": "^7.16.2", "@types/jest": "^28.1.3", + "@vitejs/plugin-vue2": "^1.1.2", "@vue/compat": "^3.2.47", "@vue/compiler-sfc": "^3.2.47", "@vue/test-utils": "1.3.6", @@ -244,6 +247,7 @@ "@vue/vue3-jest": "^29.2.3", "ajv": "^8.10.0", "ajv-formats": "^2.1.1", + "autoprefixer": "^10.4.8", "axios-mock-adapter": "^1.15.0", "babel-jest": "^28.1.3", "chalk": "^2.4.1", @@ -283,6 +287,9 @@ "stylelint": "^14.9.1", "swagger-cli": "^4.0.4", "timezone-mock": "^1.0.8", + "vite": "^4.4.9", + "vite-plugin-ruby": "^3.2.2", + "vite-svg-loader": "^3.4.0", "vue-loader-vue3": "npm:vue-loader@17", "vue-test-utils-compat": "0.0.13", "vuex-mock-store": "^0.1.0", diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 00000000000..a47ef4f9528 --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,5 @@ +module.exports = { + plugins: { + autoprefixer: {}, + }, +}; diff --git a/spec/frontend/diffs/components/diff_content_spec.js b/spec/frontend/diffs/components/diff_content_spec.js index 3b37edbcb1d..4fcc8720176 100644 --- a/spec/frontend/diffs/components/diff_content_spec.js +++ b/spec/frontend/diffs/components/diff_content_spec.js @@ -5,7 +5,6 @@ import Vuex from 'vuex'; import waitForPromises from 'helpers/wait_for_promises'; import { sprintf } from '~/locale'; import { createAlert } from '~/alert'; -import * as diffRowUtils from 'ee_else_ce/diffs/components/diff_row_utils'; import DiffContentComponent from '~/diffs/components/diff_content.vue'; import DiffDiscussions from '~/diffs/components/diff_discussions.vue'; import DiffView from '~/diffs/components/diff_view.vue'; @@ -120,32 +119,6 @@ describe('DiffContent', () => { expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(true); }); - - it('should include Sast findings when sastReportsInInlineDiff flag is true', () => { - const mapParallelSpy = jest.spyOn(diffRowUtils, 'mapParallel'); - const mapParallelNoSastSpy = jest.spyOn(diffRowUtils, 'mapParallelNoSast'); - createComponent({ - provide: { - glFeatures: { - sastReportsInInlineDiff: true, - }, - }, - props: { diffFile: { ...textDiffFile, renderingLines: true } }, - }); - - expect(mapParallelSpy).toHaveBeenCalled(); - expect(mapParallelNoSastSpy).not.toHaveBeenCalled(); - }); - - it('should not include Sast findings when sastReportsInInlineDiff flag is false', () => { - const mapParallelSpy = jest.spyOn(diffRowUtils, 'mapParallel'); - const mapParallelNoSastSpy = jest.spyOn(diffRowUtils, 'mapParallelNoSast'); - - createComponent({ props: { diffFile: { ...textDiffFile, renderingLines: true } } }); - - expect(mapParallelNoSastSpy).toHaveBeenCalled(); - expect(mapParallelSpy).not.toHaveBeenCalled(); - }); }); describe('with whitespace only change', () => { diff --git a/spec/frontend/diffs/components/diff_line_spec.js b/spec/frontend/diffs/components/diff_line_spec.js index 02424c8d359..501bd0757c8 100644 --- a/spec/frontend/diffs/components/diff_line_spec.js +++ b/spec/frontend/diffs/components/diff_line_spec.js @@ -16,13 +16,6 @@ const left = { severity: EXAMPLE_SEVERITY, }, ], - sast: [ - { - line: EXAMPLE_LINE_NUMBER, - description: EXAMPLE_DESCRIPTION, - severity: EXAMPLE_SEVERITY, - }, - ], }, }, }; @@ -37,13 +30,6 @@ const right = { severity: EXAMPLE_SEVERITY, }, ], - sast: [ - { - line: EXAMPLE_LINE_NUMBER, - description: EXAMPLE_DESCRIPTION, - severity: EXAMPLE_SEVERITY, - }, - ], }, }, }; @@ -74,13 +60,6 @@ describe('DiffLine', () => { severity: EXAMPLE_SEVERITY, }, ]); - expect(wrapper.findComponent(InlineFindings).props('sast')).toEqual([ - { - line: EXAMPLE_LINE_NUMBER, - description: EXAMPLE_DESCRIPTION, - severity: EXAMPLE_SEVERITY, - }, - ]); }); }); }); diff --git a/spec/frontend/diffs/components/diff_view_spec.js b/spec/frontend/diffs/components/diff_view_spec.js index 6962d8d819b..25d1935c7cd 100644 --- a/spec/frontend/diffs/components/diff_view_spec.js +++ b/spec/frontend/diffs/components/diff_view_spec.js @@ -18,7 +18,7 @@ describe('DiffView', () => { const setSelectedCommentPosition = jest.fn(); const getDiffRow = (wrapper) => wrapper.findComponent(DiffRow).vm; - const createWrapper = (props) => { + const createWrapper = ({ props, flag = false } = {}) => { Vue.use(Vuex); const batchComments = { @@ -50,9 +50,21 @@ describe('DiffView', () => { diffFile: { file_hash: '123' }, diffLines: [], ...props, + provide: { + glFeatures: { + sastReportsInInlineDiff: flag, + }, + }, }; + + const provide = { + glFeatures: { + sastReportsInInlineDiff: flag, + }, + }; + const stubs = { DiffExpansionCell, DiffRow, DiffCommentCell, DraftNote }; - return shallowMount(DiffView, { propsData, store, stubs }); + return shallowMount(DiffView, { propsData, provide, store, stubs }); }; beforeEach(() => { @@ -69,12 +81,26 @@ describe('DiffView', () => { }); it('does render a diff-line component with the correct props when there is a finding', async () => { - const wrapper = createWrapper(diffCodeQuality); + const wrapper = createWrapper({ props: diffCodeQuality }); wrapper.findComponent(DiffRow).vm.$emit('toggleCodeQualityFindings', 2); await nextTick(); expect(wrapper.findComponent(DiffLine).props('line')).toBe(diffCodeQuality.diffLines[2]); }); + it('does not render a diff-line component when there is a finding and sastReportsInInlineDiff flag is true', async () => { + const wrapper = createWrapper({ props: diffCodeQuality, flag: true }); + wrapper.findComponent(DiffRow).vm.$emit('toggleCodeQualityFindings', 2); + await nextTick(); + expect(wrapper.findComponent(DiffLine).exists()).toBe(false); + }); + + it('does render a diff-line component when there is a finding and sastReportsInInlineDiff flag is false', async () => { + const wrapper = createWrapper({ props: diffCodeQuality }); + wrapper.findComponent(DiffRow).vm.$emit('toggleCodeQualityFindings', 2); + await nextTick(); + expect(wrapper.findComponent(DiffLine).exists()).toBe(true); + }); + it.each` type | side | container | sides | total ${'parallel'} | ${'left'} | ${'.old'} | ${{ left: { lineDrafts: [], renderDiscussion: true }, right: { lineDrafts: [], renderDiscussion: true } }} | ${2} @@ -86,8 +112,10 @@ describe('DiffView', () => { 'renders a $type comment row with comment cell on $side', ({ type, container, sides, total }) => { const wrapper = createWrapper({ - diffLines: [{ renderCommentRow: true, ...sides }], - inline: type === 'inline', + props: { + diffLines: [{ renderCommentRow: true, ...sides }], + inline: type === 'inline', + }, }); expect(wrapper.findAllComponents(DiffCommentCell).length).toBe(total); expect(wrapper.find(container).findComponent(DiffCommentCell).exists()).toBe(true); @@ -96,21 +124,20 @@ describe('DiffView', () => { it('renders a draft row', () => { const wrapper = createWrapper({ - diffLines: [{ renderCommentRow: true, left: { lineDrafts: [{ isDraft: true }] } }], + props: { diffLines: [{ renderCommentRow: true, left: { lineDrafts: [{ isDraft: true }] } }] }, }); expect(wrapper.findComponent(DraftNote).exists()).toBe(true); }); describe('drag operations', () => { it('sets `dragStart` onStartDragging', () => { - const wrapper = createWrapper({ diffLines: [{}] }); - + const wrapper = createWrapper({ props: { diffLines: [{}] } }); wrapper.findComponent(DiffRow).vm.$emit('startdragging', { line: { test: true } }); expect(wrapper.vm.idState.dragStart).toEqual({ test: true }); }); it('does not call `setSelectedCommentPosition` on different chunks onDragOver', () => { - const wrapper = createWrapper({ diffLines: [{}] }); + const wrapper = createWrapper({ props: { diffLines: [{}] } }); const diffRow = getDiffRow(wrapper); diffRow.$emit('startdragging', { line: { chunk: 0 } }); @@ -127,7 +154,7 @@ describe('DiffView', () => { `( 'calls `setSelectedCommentPosition` with correct `updatedLineRange`', ({ start, end, expectation }) => { - const wrapper = createWrapper({ diffLines: [{}] }); + const wrapper = createWrapper({ props: { diffLines: [{}] } }); const diffRow = getDiffRow(wrapper); diffRow.$emit('startdragging', { line: { chunk: 1, index: start } }); @@ -140,7 +167,7 @@ describe('DiffView', () => { ); it('sets `dragStart` to null onStopDragging', () => { - const wrapper = createWrapper({ diffLines: [{}] }); + const wrapper = createWrapper({ props: { diffLines: [{}] } }); const diffRow = getDiffRow(wrapper); diffRow.$emit('startdragging', { line: { test: true } }); @@ -152,7 +179,8 @@ describe('DiffView', () => { }); it('throttles multiple calls to enterdragging', () => { - const wrapper = createWrapper({ diffLines: [{}] }); + const wrapper = createWrapper({ props: { diffLines: [{}] } }); + const diffRow = getDiffRow(wrapper); diffRow.$emit('startdragging', { line: { chunk: 1, index: 1 } }); diff --git a/spec/frontend/diffs/components/inline_findings_spec.js b/spec/frontend/diffs/components/inline_findings_spec.js index ea785622f0f..71cc6ae49fd 100644 --- a/spec/frontend/diffs/components/inline_findings_spec.js +++ b/spec/frontend/diffs/components/inline_findings_spec.js @@ -1,27 +1,24 @@ import { mountExtended } from 'helpers/vue_test_utils_helper'; import InlineFindings from '~/diffs/components/inline_findings.vue'; import DiffInlineFindings from '~/diffs/components/diff_inline_findings.vue'; -import { NEW_CODE_QUALITY_FINDINGS, NEW_SAST_FINDINGS } from '~/diffs/i18n'; -import { multipleCodeQualityNoSast, multipleSastNoCodeQuality } from '../mock_data/inline_findings'; +import { NEW_CODE_QUALITY_FINDINGS } from '~/diffs/i18n'; +import { threeCodeQualityFindingsRaw } from '../mock_data/inline_findings'; let wrapper; const diffInlineFindings = () => wrapper.findComponent(DiffInlineFindings); -const allDiffInlineFindings = () => wrapper.findAllComponents(DiffInlineFindings); describe('InlineFindings', () => { - const createWrapper = (findings) => { + const createWrapper = () => { return mountExtended(InlineFindings, { propsData: { - expandedLines: [], - codeQuality: findings.codeQuality, - sast: findings.sast, + codeQuality: threeCodeQualityFindingsRaw, }, }); }; it('hides details and throws hideInlineFindings event on close click', async () => { - wrapper = createWrapper(multipleCodeQualityNoSast); + wrapper = createWrapper(); expect(wrapper.findByTestId('inline-findings').exists()).toBe(true); await wrapper.findByTestId('inline-findings-close').trigger('click'); @@ -29,30 +26,8 @@ describe('InlineFindings', () => { }); it('renders diff inline findings component with correct props for codequality array', () => { - wrapper = createWrapper(multipleCodeQualityNoSast); - + wrapper = createWrapper(); expect(diffInlineFindings().props('title')).toBe(NEW_CODE_QUALITY_FINDINGS); - expect(diffInlineFindings().props('findings')).toBe(multipleCodeQualityNoSast.codeQuality); - }); - - it('does not render codeQuality section when codeQuality array is empty', () => { - wrapper = createWrapper(multipleSastNoCodeQuality); - - expect(diffInlineFindings().props('title')).toBe(NEW_SAST_FINDINGS); - expect(allDiffInlineFindings()).toHaveLength(1); - }); - - it('renders heading and correct amount of list items for sast array and their description', () => { - wrapper = createWrapper(multipleSastNoCodeQuality); - - expect(diffInlineFindings().props('title')).toBe(NEW_SAST_FINDINGS); - expect(diffInlineFindings().props('findings')).toBe(multipleSastNoCodeQuality.sast); - }); - - it('does not render sast section when sast array is empty', () => { - wrapper = createWrapper(multipleCodeQualityNoSast); - - expect(diffInlineFindings().props('title')).toBe(NEW_CODE_QUALITY_FINDINGS); - expect(allDiffInlineFindings()).toHaveLength(1); + expect(diffInlineFindings().props('findings')).toBe(threeCodeQualityFindingsRaw); }); }); diff --git a/spec/frontend/diffs/mock_data/inline_findings.js b/spec/frontend/diffs/mock_data/inline_findings.js index 5b9ed538e01..85fb48b86d5 100644 --- a/spec/frontend/diffs/mock_data/inline_findings.js +++ b/spec/frontend/diffs/mock_data/inline_findings.js @@ -95,6 +95,7 @@ export const threeCodeQualityFindings = { filePath: 'index.js', codequality: multipleFindingsArrCodeQualityScale.slice(0, 3), }; +export const threeCodeQualityFindingsRaw = [multipleFindingsArrCodeQualityScale.slice(0, 3)]; export const singularCodeQualityFinding = { filePath: 'index.js', diff --git a/spec/graphql/resolvers/metrics/dashboards/annotation_resolver_spec.rb b/spec/graphql/resolvers/metrics/dashboards/annotation_resolver_spec.rb index 16e619cf9cd..75e0a816086 100644 --- a/spec/graphql/resolvers/metrics/dashboards/annotation_resolver_spec.rb +++ b/spec/graphql/resolvers/metrics/dashboards/annotation_resolver_spec.rb @@ -7,13 +7,12 @@ RSpec.describe Resolvers::Metrics::Dashboards::AnnotationResolver, feature_categ describe '#resolve' do context 'user with developer access' do - subject(:resolve_annotations) { resolve(described_class, obj: dashboard, args: args, ctx: { current_user: current_user }) } + subject(:resolve_annotations) { resolve(described_class, obj: nil, args: args, ctx: { current_user: current_user }) } let_it_be(:current_user) { create(:user) } let_it_be(:environment) { create(:environment) } let_it_be(:path) { 'config/prometheus/common_metrics.yml' } - let(:dashboard) { PerformanceMonitoring::PrometheusDashboard.new(path: path, environment: environment) } let(:args) do { from: 10.minutes.ago, diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index ad81c125055..1903b60a126 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -891,4 +891,38 @@ RSpec.describe ApplicationHelper do end end end + + describe '#controller_full_path' do + let(:path) { 'some_path' } + let(:action) { 'show' } + + before do + allow(helper.controller).to receive(:controller_path).and_return(path) + allow(helper.controller).to receive(:action_name).and_return(action) + end + + context 'when is create action' do + let(:action) { 'create' } + + it 'transforms to "new" path' do + expect(helper.controller_full_path).to eq("#{path}/new") + end + end + + context 'when is update action' do + let(:action) { 'update' } + + it 'transforms to "edit" path' do + expect(helper.controller_full_path).to eq("#{path}/edit") + end + end + + context 'when is show action' do + let(:action) { 'show' } + + it 'passes through' do + expect(helper.controller_full_path).to eq("#{path}/#{action}") + end + end + end end diff --git a/spec/helpers/vite_helper_spec.rb b/spec/helpers/vite_helper_spec.rb new file mode 100644 index 00000000000..edb5650ab1a --- /dev/null +++ b/spec/helpers/vite_helper_spec.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe ViteHelper, feature_category: :tooling do + let(:source) { 'foo.js' } + let(:vite_source) { 'vite/foo.js' } + let(:vite_tag) { '' } + let(:webpack_source) { 'webpack/foo.js' } + let(:webpack_tag) { '' } + + context 'when vite enabled' do + before do + stub_rails_env('development') + stub_feature_flags(vite: true) + + allow(helper).to receive(:vite_javascript_tag).and_return(vite_tag) + allow(helper).to receive(:vite_asset_path).and_return(vite_source) + allow(helper).to receive(:vite_stylesheet_tag).and_return(vite_tag) + allow(helper).to receive(:vite_asset_url).and_return(vite_source) + allow(helper).to receive(:vite_running).and_return(true) + end + + describe '#universal_javascript_include_tag' do + it 'returns vite javascript tag' do + expect(helper.universal_javascript_include_tag(source)).to eq(vite_tag) + end + end + + describe '#universal_asset_path' do + it 'returns vite asset path' do + expect(helper.universal_asset_path(source)).to eq(vite_source) + end + end + end + + context 'when vite disabled' do + before do + stub_feature_flags(vite: false) + + allow(helper).to receive(:javascript_include_tag).and_return(webpack_tag) + allow(helper).to receive(:asset_path).and_return(webpack_source) + allow(helper).to receive(:stylesheet_link_tag).and_return(webpack_tag) + allow(helper).to receive(:path_to_stylesheet).and_return(webpack_source) + end + + describe '#universal_javascript_include_tag' do + it 'returns webpack javascript tag' do + expect(helper.universal_javascript_include_tag(source)).to eq(webpack_tag) + end + end + + describe '#universal_asset_path' do + it 'returns ActionView asset path' do + expect(helper.universal_asset_path(source)).to eq(webpack_source) + end + end + end +end diff --git a/spec/helpers/webpack_helper_spec.rb b/spec/helpers/webpack_helper_spec.rb index f9e2d265153..23585c47239 100644 --- a/spec/helpers/webpack_helper_spec.rb +++ b/spec/helpers/webpack_helper_spec.rb @@ -34,4 +34,22 @@ RSpec.describe WebpackHelper do expect(output).to eq("") end end + + context 'when vite enabled' do + let(:bundle) { 'bundle.js' } + + before do + stub_rails_env('development') + stub_feature_flags(vite: true) + + allow(helper).to receive(:vite_javascript_tag).and_return('vite') + allow(helper).to receive(:vite_running).and_return(true) + end + + describe '#webpack_bundle_tag' do + it 'return vite javascript tag' do + expect(helper.webpack_bundle_tag(bundle)).to eq('vite') + end + end + end end diff --git a/spec/lib/backup/gitaly_backup_spec.rb b/spec/lib/backup/gitaly_backup_spec.rb index 40e835e9dc8..f5b47e39fdb 100644 --- a/spec/lib/backup/gitaly_backup_spec.rb +++ b/spec/lib/backup/gitaly_backup_spec.rb @@ -7,6 +7,7 @@ RSpec.describe Backup::GitalyBackup, feature_category: :backup_restore do let(:storage_parallelism) { nil } let(:destination) { File.join(Gitlab.config.backup.path, 'repositories') } let(:backup_id) { '20220101' } + let(:server_side) { false } let(:progress) do Tempfile.new('progress').tap do |progress| @@ -26,7 +27,14 @@ RSpec.describe Backup::GitalyBackup, feature_category: :backup_restore do progress.close end - subject { described_class.new(progress, max_parallelism: max_parallelism, storage_parallelism: storage_parallelism) } + subject do + described_class.new( + progress, + max_parallelism: max_parallelism, + storage_parallelism: storage_parallelism, + server_side: server_side + ) + end context 'unknown' do it 'fails to start unknown' do @@ -92,6 +100,17 @@ RSpec.describe Backup::GitalyBackup, feature_category: :backup_restore do end end + context 'server-side option set' do + let(:server_side) { true } + + it 'passes option through' do + expect(Open3).to receive(:popen2).with(expected_env, anything, 'create', '-server-side', '-id', backup_id).and_call_original + + subject.start(:create, destination, backup_id: backup_id) + subject.finish! + end + end + it 'raises when the exit code not zero' do expect(subject).to receive(:bin_path).and_return(Gitlab::Utils.which('false')) @@ -209,6 +228,35 @@ RSpec.describe Backup::GitalyBackup, feature_category: :backup_restore do end end + context 'server-side option set' do + let(:server_side) { true } + + it 'passes option through' do + expect(Open3).to receive(:popen2).with(expected_env, anything, 'restore', '-server-side', '-id', backup_id).and_call_original + + subject.start(:restore, destination, backup_id: backup_id) + subject.finish! + end + + context 'missing backup_id' do + it 'wont set the option' do + expect(Open3).to receive(:popen2).with(expected_env, anything, 'restore', '-server-side').and_call_original + + subject.start(:restore, destination) + subject.finish! + end + end + end + + context 'missing backup_id' do + it 'wont set the option' do + expect(Open3).to receive(:popen2).with(expected_env, anything, 'restore', '-path', anything, '-layout', 'pointer').and_call_original + + subject.start(:restore, destination) + subject.finish! + end + end + it 'raises when the exit code not zero' do expect(subject).to receive(:bin_path).and_return(Gitlab::Utils.which('false')) diff --git a/spec/lib/gitlab/metrics/dashboard/finder_spec.rb b/spec/lib/gitlab/metrics/dashboard/finder_spec.rb deleted file mode 100644 index e94816c102f..00000000000 --- a/spec/lib/gitlab/metrics/dashboard/finder_spec.rb +++ /dev/null @@ -1,62 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Gitlab::Metrics::Dashboard::Finder, :use_clean_rails_memory_store_caching do - include MetricsDashboardHelpers - - let_it_be(:project) { create(:project) } - let_it_be(:user) { create(:user) } - let_it_be(:environment) { create(:environment, project: project) } - - before do - project.add_maintainer(user) - end - - describe '.find' do - let(:dashboard_path) { '.gitlab/dashboards/test.yml' } - let(:service_call) { described_class.find(project, user, environment: environment, dashboard_path: dashboard_path) } - - context 'when the dashboard exists' do - let(:project) { project_with_dashboard(dashboard_path) } - - it_behaves_like 'valid dashboard service response' - end - - context 'when the system dashboard is specified' do - let(:dashboard_path) { system_dashboard_path } - - it_behaves_like 'valid dashboard service response' - end - - context 'when no dashboard is specified' do - let(:service_call) { described_class.find(project, user, environment: environment) } - - it_behaves_like 'valid dashboard service response' - end - end - - describe '.find_raw' do - let(:dashboard) { load_dashboard_yaml(File.read(Rails.root.join('config', 'prometheus', 'common_metrics.yml'))) } - let(:params) { {} } - - subject { described_class.find_raw(project, **params) } - - it { is_expected.to eq dashboard } - - context 'when the system dashboard is specified' do - let(:params) { { dashboard_path: system_dashboard_path } } - - it { is_expected.to eq dashboard } - end - end - - describe '.find_all_paths' do - let(:all_dashboard_paths) { described_class.find_all_paths(project) } - let(:system_dashboard) { { path: system_dashboard_path, display_name: 'Overview', default: true, system_dashboard: true, out_of_the_box_dashboard: true } } - - it 'includes OOTB dashboards by default' do - expect(all_dashboard_paths).to eq([system_dashboard]) - end - end -end diff --git a/spec/lib/gitlab/metrics/dashboard/service_selector_spec.rb b/spec/lib/gitlab/metrics/dashboard/service_selector_spec.rb deleted file mode 100644 index cabd453cc3a..00000000000 --- a/spec/lib/gitlab/metrics/dashboard/service_selector_spec.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Gitlab::Metrics::Dashboard::ServiceSelector do - include MetricsDashboardHelpers - - describe '#call' do - let(:arguments) { {} } - - subject { described_class.call(arguments) } - - it { is_expected.to be Metrics::Dashboard::SystemDashboardService } - - context 'when just the dashboard path is provided' do - context 'when the path is for the system dashboard' do - let(:arguments) { { dashboard_path: system_dashboard_path } } - - it { is_expected.to be Metrics::Dashboard::SystemDashboardService } - end - end - end -end diff --git a/spec/models/performance_monitoring/prometheus_dashboard_spec.rb b/spec/models/performance_monitoring/prometheus_dashboard_spec.rb deleted file mode 100644 index 56d416356fe..00000000000 --- a/spec/models/performance_monitoring/prometheus_dashboard_spec.rb +++ /dev/null @@ -1,244 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe PerformanceMonitoring::PrometheusDashboard do - let(:json_content) do - { - "dashboard" => "Dashboard Title", - "templating" => { - "variables" => { - "variable1" => %w(value1 value2 value3) - } - }, - "panel_groups" => [{ - "group" => "Group Title", - "panels" => [{ - "type" => "area-chart", - "title" => "Chart Title", - "y_label" => "Y-Axis", - "metrics" => [{ - "id" => "metric_of_ages", - "unit" => "count", - "label" => "Metric of Ages", - "query_range" => "http_requests_total" - }] - }] - }] - } - end - - describe '.from_json' do - subject { described_class.from_json(json_content) } - - it 'creates a PrometheusDashboard object' do - expect(subject).to be_a described_class - expect(subject.dashboard).to eq(json_content['dashboard']) - expect(subject.panel_groups).to all(be_a PerformanceMonitoring::PrometheusPanelGroup) - end - - describe 'validations' do - shared_examples 'validation failed' do |errors_messages| - it 'raises error with corresponding messages', :aggregate_failures do - expect { subject }.to raise_error do |error| - expect(error).to be_kind_of(ActiveModel::ValidationError) - expect(error.model.errors.messages).to eq(errors_messages) - end - end - end - - context 'dashboard content is missing' do - let(:json_content) { nil } - - it_behaves_like 'validation failed', panel_groups: ["should be an array of panel_groups objects"], dashboard: ["can't be blank"] - end - - context 'dashboard content is NOT a hash' do - let(:json_content) { YAML.safe_load("'test'") } - - it_behaves_like 'validation failed', panel_groups: ["should be an array of panel_groups objects"], dashboard: ["can't be blank"] - end - - context 'content is an array' do - let(:json_content) { [{ "dashboard" => "Dashboard Title" }] } - - it_behaves_like 'validation failed', panel_groups: ["should be an array of panel_groups objects"], dashboard: ["can't be blank"] - end - - context 'dashboard definition is missing panels_groups and dashboard keys' do - let(:json_content) do - { - "dashboard" => nil - } - end - - it_behaves_like 'validation failed', panel_groups: ["should be an array of panel_groups objects"], dashboard: ["can't be blank"] - end - - context 'group definition is missing panels and group keys' do - let(:json_content) do - { - "dashboard" => "Dashboard Title", - "templating" => { - "variables" => { - "variable1" => %w(value1 value2 value3) - } - }, - "panel_groups" => [{ "group" => nil }] - } - end - - it_behaves_like 'validation failed', panels: ["should be an array of panels objects"], group: ["can't be blank"] - end - - context 'panel definition is missing metrics and title keys' do - let(:json_content) do - { - "dashboard" => "Dashboard Title", - "templating" => { - "variables" => { - "variable1" => %w(value1 value2 value3) - } - }, - "panel_groups" => [{ - "group" => "Group Title", - "panels" => [{ - "type" => "area-chart", - "y_label" => "Y-Axis" - }] - }] - } - end - - it_behaves_like 'validation failed', metrics: ["should be an array of metrics objects"], title: ["can't be blank"] - end - - context 'metrics definition is missing unit, query and query_range keys' do - let(:json_content) do - { - "dashboard" => "Dashboard Title", - "templating" => { - "variables" => { - "variable1" => %w(value1 value2 value3) - } - }, - "panel_groups" => [{ - "group" => "Group Title", - "panels" => [{ - "type" => "area-chart", - "title" => "Chart Title", - "y_label" => "Y-Axis", - "metrics" => [{ - "id" => "metric_of_ages", - "label" => "Metric of Ages", - "query_range" => nil - }] - }] - }] - } - end - - it_behaves_like 'validation failed', unit: ["can't be blank"], query_range: ["can't be blank"], query: ["can't be blank"] - end - - # for each parent entry validation first is done to its children, - # whole execution is stopped on first encountered error - # which is the one that is reported - context 'multiple offences on different levels' do - let(:json_content) do - { - "dashboard" => nil, - "panel_groups" => [{ - "group" => nil, - "panels" => [{ - "type" => "area-chart", - "title" => nil, - "y_label" => "Y-Axis", - "metrics" => [{ - "id" => "metric_of_ages", - "label" => "Metric of Ages", - "query_range" => 'query' - }, { - "id" => "metric_of_ages", - "unit" => "count", - "label" => "Metric of Ages", - "query_range" => nil - }] - }] - }, { - "group" => 'group', - "panels" => nil - }] - } - end - - it_behaves_like 'validation failed', unit: ["can't be blank"] - end - end - end - - describe '.find_for' do - let(:project) { build_stubbed(:project) } - let(:user) { build_stubbed(:user) } - let(:environment) { build_stubbed(:environment, project: project) } - let(:path) { ::Metrics::Dashboard::SystemDashboardService::DASHBOARD_PATH } - - context 'dashboard has been found' do - it 'uses dashboard finder to find and load dashboard data and returns dashboard instance', :aggregate_failures do - expect(Gitlab::Metrics::Dashboard::Finder).to receive(:find).with(project, user, { environment: environment, dashboard_path: path }).and_return(status: :success, dashboard: json_content) - - dashboard_instance = described_class.find_for(project: project, user: user, path: path, options: { environment: environment }) - - expect(dashboard_instance).to be_instance_of described_class - expect(dashboard_instance.environment).to eq environment - expect(dashboard_instance.path).to eq path - end - end - - context 'dashboard has NOT been found' do - it 'returns nil' do - allow(Gitlab::Metrics::Dashboard::Finder).to receive(:find).and_return(http_status: :not_found) - - dashboard_instance = described_class.find_for(project: project, user: user, path: path, options: { environment: environment }) - - expect(dashboard_instance).to be_nil - end - end - - context 'dashboard has invalid schema', :aggregate_failures do - it 'still returns dashboard object' do - expect(Gitlab::Metrics::Dashboard::Finder).to receive(:find).and_return(http_status: :unprocessable_entity) - - dashboard_instance = described_class.find_for(project: project, user: user, path: path, options: { environment: environment }) - - expect(dashboard_instance).to be_instance_of described_class - expect(dashboard_instance.environment).to eq environment - expect(dashboard_instance.path).to eq path - end - end - end - - describe '#schema_validation_warnings' do - let(:environment) { create(:environment, project: project) } - let(:path) { '.gitlab/dashboards/test.yml' } - let(:project) { create(:project, :repository, :custom_repo, files: { path => dashboard_schema.to_yaml }) } - - subject(:schema_validation_warnings) { described_class.new(dashboard_schema.merge(path: path, environment: environment)).schema_validation_warnings } - - before do - allow(Gitlab::Metrics::Dashboard::Finder).to receive(:find_raw).with(project, dashboard_path: path).and_call_original - end - - context 'when schema is invalid' do - let(:dashboard_schema) { YAML.safe_load(fixture_file('lib/gitlab/metrics/dashboard/dashboard_missing_panel_groups.yml')) } - - it 'returns array with errors messages' do - instance = described_class.new - instance.errors.add(:test, 'test error') - - expect(described_class).to receive(:from_json).and_raise(ActiveModel::ValidationError.new(instance)) - expect(described_class.new.schema_validation_warnings).to eq ['test: test error'] - end - end - end -end diff --git a/spec/requests/content_security_policy_spec.rb b/spec/requests/content_security_policy_spec.rb index 3f0665f1ce5..dcd55b1eeee 100644 --- a/spec/requests/content_security_policy_spec.rb +++ b/spec/requests/content_security_policy_spec.rb @@ -7,6 +7,7 @@ require 'spec_helper' # of testing in application_controller_spec. RSpec.describe 'Content Security Policy', feature_category: :application_instrumentation do let(:snowplow_host) { 'snowplow.example.com' } + let(:vite_origin) { "#{ViteRuby.instance.config.host}:#{ViteRuby.instance.config.port}" } shared_examples 'snowplow is not in the CSP' do it 'does not add the snowplow collector hostname to the CSP' do @@ -46,5 +47,32 @@ RSpec.describe 'Content Security Policy', feature_category: :application_instrum it_behaves_like 'snowplow is not in the CSP' end + + context 'when vite enabled during development' do + before do + stub_rails_env('development') + stub_feature_flags(vite: true) + + get explore_root_url + end + + it 'adds vite csp' do + expect(response).to have_gitlab_http_status(:ok) + expect(response.headers['Content-Security-Policy']).to include(vite_origin) + end + end + + context 'when vite disabled' do + before do + stub_feature_flags(vite: false) + + get explore_root_url + end + + it "doesn't add vite csp" do + expect(response).to have_gitlab_http_status(:ok) + expect(response.headers['Content-Security-Policy']).not_to include(vite_origin) + end + end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 60655a3cf50..1880acaeb05 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -345,6 +345,8 @@ RSpec.configure do |config| # Keep-around refs should only be turned off for specific projects/repositories. stub_feature_flags(disable_keep_around_refs: false) + stub_feature_flags(vite: false) + allow(Gitlab::GitalyClient).to receive(:can_use_disk?).and_return(enable_rugged) else unstub_all_feature_flags diff --git a/spec/support/shared_contexts/policies/group_policy_shared_context.rb b/spec/support/shared_contexts/policies/group_policy_shared_context.rb index 0bb7ef9e319..07a4cbdb534 100644 --- a/spec/support/shared_contexts/policies/group_policy_shared_context.rb +++ b/spec/support/shared_contexts/policies/group_policy_shared_context.rb @@ -74,7 +74,6 @@ RSpec.shared_context 'GroupPolicy context' do read_statistics update_default_branch_protection read_group_runners - admin_group_runners register_group_runners read_billing edit_billing diff --git a/spec/support/shared_examples/services/metrics/dashboard_shared_examples.rb b/spec/support/shared_examples/services/metrics/dashboard_shared_examples.rb index bdb01b12607..9b2e038a331 100644 --- a/spec/support/shared_examples/services/metrics/dashboard_shared_examples.rb +++ b/spec/support/shared_examples/services/metrics/dashboard_shared_examples.rb @@ -124,27 +124,6 @@ RSpec.shared_examples 'valid dashboard cloning process' do |dashboard_template, end end -RSpec.shared_examples 'valid dashboard update process' do - let(:dashboard_attrs) do - { - commit_message: commit_message, - branch_name: branch, - start_branch: project.default_branch, - encoding: 'text', - file_path: ".gitlab/dashboards/#{file_name}", - file_content: ::PerformanceMonitoring::PrometheusDashboard.from_json(file_content_hash).to_yaml - } - end - - it 'delegates commit creation to Files::UpdateService', :aggregate_failures do - service_instance = instance_double(::Files::UpdateService) - expect(::Files::UpdateService).to receive(:new).with(project, user, dashboard_attrs).and_return(service_instance) - expect(service_instance).to receive(:execute).and_return(status: :success) - - service_call - end -end - RSpec.shared_examples 'misconfigured dashboard service response with stepable' do |status_code, message = nil| it 'returns an appropriate message and status code', :aggregate_failures do result = service_call diff --git a/spec/tasks/gitlab/backup_rake_spec.rb b/spec/tasks/gitlab/backup_rake_spec.rb index 414ce01917b..04634af12a8 100644 --- a/spec/tasks/gitlab/backup_rake_spec.rb +++ b/spec/tasks/gitlab/backup_rake_spec.rb @@ -578,7 +578,8 @@ RSpec.describe 'gitlab:backup namespace rake tasks', :delete, feature_category: anything, max_parallelism: 5, storage_parallelism: 2, - incremental: false + incremental: false, + server_side: false ).and_call_original expect { run_rake_task('gitlab:backup:create') }.to output.to_stdout_from_any_process diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 00000000000..fb036ae6068 --- /dev/null +++ b/vite.config.js @@ -0,0 +1,100 @@ +import path from 'path'; +import { defineConfig } from 'vite'; +import svgLoader from 'vite-svg-loader'; +import vue from '@vitejs/plugin-vue2'; +import graphql from '@rollup/plugin-graphql'; +import RubyPlugin from 'vite-plugin-ruby'; +import { viteCommonjs } from '@originjs/vite-plugin-commonjs'; +import webpackConfig from './config/webpack.config'; +import { + IS_EE, + IS_JH, + SOURCEGRAPH_PUBLIC_PATH, + GITLAB_WEB_IDE_PUBLIC_PATH, +} from './config/webpack.constants'; +import viteSharedConfig from './config/vite.json'; + +const aliasArr = Object.entries(webpackConfig.resolve.alias).map(([find, replacement]) => ({ + find: find.includes('$') ? new RegExp(find) : find, + replacement, +})); + +const assetsPath = path.resolve(__dirname, 'app/assets'); +const javascriptsPath = path.resolve(assetsPath, 'javascripts'); + +const emptyComponent = path.resolve(javascriptsPath, 'vue_shared/components/empty_component.js'); + +const [rubyPlugin, ...rest] = RubyPlugin(); + +// We can't use regular 'resolve' which points to sourceCodeDir in vite.json +// Because we need for '~' alias to resolve to app/assets/javascripts +// We can't use javascripts folder in sourceCodeDir because we also need to resolve other assets +// With undefined 'resolve' an '~' alias from Webpack config is used instead +// See the issue for details: https://github.com/ElMassimo/vite_ruby/issues/237 +const fixedRubyPlugin = [ + { + ...rubyPlugin, + config: (...args) => { + const originalConfig = rubyPlugin.config(...args); + return { + ...originalConfig, + resolve: undefined, + }; + }, + }, + ...rest, +]; + +const EE_ALIAS_FALLBACK = [ + { + find: /^ee_component\/(.*)\.vue/, + replacement: emptyComponent, + }, +]; + +const JH_ALIAS_FALLBACK = [ + { + find: /^jh_component\/(.*)\.vue/, + replacement: emptyComponent, + }, +]; + +export default defineConfig({ + resolve: { + alias: [ + ...aliasArr, + ...(IS_EE ? [] : EE_ALIAS_FALLBACK), + ...(IS_JH ? [] : JH_ALIAS_FALLBACK), + { + find: '~/', + replacement: javascriptsPath, + }, + ], + }, + plugins: [ + fixedRubyPlugin, + vue(), + graphql(), + svgLoader({ + defaultImport: 'raw', + }), + viteCommonjs({ + include: [path.resolve(javascriptsPath, 'locale/ensure_single_line.cjs')], + }), + ], + define: { + IS_EE: IS_EE ? 'window.gon && window.gon.ee' : JSON.stringify(false), + IS_JH: IS_JH ? 'window.gon && window.gon.jh' : JSON.stringify(false), + 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV), + 'process.env.SOURCEGRAPH_PUBLIC_PATH': JSON.stringify(SOURCEGRAPH_PUBLIC_PATH), + 'process.env.GITLAB_WEB_IDE_PUBLIC_PATH': JSON.stringify(GITLAB_WEB_IDE_PUBLIC_PATH), + }, + server: { + hmr: { + host: viteSharedConfig?.development?.host || 'localhost', + // ensure we stay compatible with HTTPS enabled for GDK + protocol: 'ws', + }, + https: false, + }, +}); diff --git a/yarn.lock b/yarn.lock index 145eb3e665e..8326b53eab8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -328,9 +328,9 @@ js-tokens "^4.0.0" "@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.16.4", "@babel/parser@^7.16.8", "@babel/parser@^7.18.10", "@babel/parser@^7.18.4", "@babel/parser@^7.19.0": - version "7.21.2" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.2.tgz#dacafadfc6d7654c3051a66d6fe55b6cb2f2a0b3" - integrity sha512-URpaIJQwEkEC2T9Kn+Ai6Xe/02iNaVCuT/PtoRz3GPVJVDpPd7mLo+VddTbhCRU9TXqW5mSrQfXZyi8kDKOVpQ== + version "7.21.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.3.tgz#1d285d67a19162ff9daa358d4cb41d50c06220b3" + integrity sha512-lobG0d7aOfQRXh8AyklEAgZGvA4FShxo6xQbUrrT/cNBPUdIDojlokwJsQyCC/eKia7ifqM0yP+2DRZ4WKw2RQ== "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.17.12": version "7.17.12" @@ -1037,6 +1037,121 @@ resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== +"@esbuild/android-arm64@0.18.15": + version "0.18.15" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.18.15.tgz#abbe87b815d2f95ec749ffb4eba65d7d5343411f" + integrity sha512-NI/gnWcMl2kXt1HJKOn2H69SYn4YNheKo6NZt1hyfKWdMbaGadxjZIkcj4Gjk/WPxnbFXs9/3HjGHaknCqjrww== + +"@esbuild/android-arm@0.18.15": + version "0.18.15" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.18.15.tgz#6afedd79c68d5d4d1e434e20a9ab620bb5849372" + integrity sha512-wlkQBWb79/jeEEoRmrxt/yhn5T1lU236OCNpnfRzaCJHZ/5gf82uYx1qmADTBWE0AR/v7FiozE1auk2riyQd3w== + +"@esbuild/android-x64@0.18.15": + version "0.18.15" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.18.15.tgz#cdd886a58748b1584ad72d960c446fa958c11ab3" + integrity sha512-FM9NQamSaEm/IZIhegF76aiLnng1kEsZl2eve/emxDeReVfRuRNmvT28l6hoFD9TsCxpK+i4v8LPpEj74T7yjA== + +"@esbuild/darwin-arm64@0.18.15": + version "0.18.15" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.18.15.tgz#648b124a6a63022adb5b0cf441e264e8f5ba4af2" + integrity sha512-XmrFwEOYauKte9QjS6hz60FpOCnw4zaPAb7XV7O4lx1r39XjJhTN7ZpXqJh4sN6q60zbP6QwAVVA8N/wUyBH/w== + +"@esbuild/darwin-x64@0.18.15": + version "0.18.15" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.18.15.tgz#91cd2601c1604d123454d325e6b24fb6438350cf" + integrity sha512-bMqBmpw1e//7Fh5GLetSZaeo9zSC4/CMtrVFdj+bqKPGJuKyfNJ5Nf2m3LknKZTS+Q4oyPiON+v3eaJ59sLB5A== + +"@esbuild/freebsd-arm64@0.18.15": + version "0.18.15" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.15.tgz#575940b0fc2f52833de4f6360445586742a8ff8b" + integrity sha512-LoTK5N3bOmNI9zVLCeTgnk5Rk0WdUTrr9dyDAQGVMrNTh9EAPuNwSTCgaKOKiDpverOa0htPcO9NwslSE5xuLA== + +"@esbuild/freebsd-x64@0.18.15": + version "0.18.15" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.15.tgz#09694fc601dd8d3263a1075977ee7d3488514ef8" + integrity sha512-62jX5n30VzgrjAjOk5orYeHFq6sqjvsIj1QesXvn5OZtdt5Gdj0vUNJy9NIpjfdNdqr76jjtzBJKf+h2uzYuTQ== + +"@esbuild/linux-arm64@0.18.15": + version "0.18.15" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.18.15.tgz#2f5d226b024964f2b5b6bce7c874a8ad31785fa2" + integrity sha512-BWncQeuWDgYv0jTNzJjaNgleduV4tMbQjmk/zpPh/lUdMcNEAxy+jvneDJ6RJkrqloG7tB9S9rCrtfk/kuplsQ== + +"@esbuild/linux-arm@0.18.15": + version "0.18.15" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.18.15.tgz#172331fc66bbe89ba96e5e2ad583b2faa132d85c" + integrity sha512-dT4URUv6ir45ZkBqhwZwyFV6cH61k8MttIwhThp2BGiVtagYvCToF+Bggyx2VI57RG4Fbt21f9TmXaYx0DeUJg== + +"@esbuild/linux-ia32@0.18.15": + version "0.18.15" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.18.15.tgz#fa797051131ee5f46d70c65a7edd14b6230cfc2f" + integrity sha512-JPXORvgHRHITqfms1dWT/GbEY89u848dC08o0yK3fNskhp0t2TuNUnsrrSgOdH28ceb1hJuwyr8R/1RnyPwocw== + +"@esbuild/linux-loong64@0.14.54": + version "0.14.54" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz#de2a4be678bd4d0d1ffbb86e6de779cde5999028" + integrity sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw== + +"@esbuild/linux-loong64@0.18.15": + version "0.18.15" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.18.15.tgz#aeae1fa3d92b1486a91c0cb1cfd9c0ebe9168de4" + integrity sha512-kArPI0DopjJCEplsVj/H+2Qgzz7vdFSacHNsgoAKpPS6W/Ndh8Oe24HRDQ5QCu4jHgN6XOtfFfLpRx3TXv/mEg== + +"@esbuild/linux-mips64el@0.18.15": + version "0.18.15" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.15.tgz#b63cfe356c33807c4d8ee5a75452922e98502073" + integrity sha512-b/tmngUfO02E00c1XnNTw/0DmloKjb6XQeqxaYuzGwHe0fHVgx5/D6CWi+XH1DvkszjBUkK9BX7n1ARTOst59w== + +"@esbuild/linux-ppc64@0.18.15": + version "0.18.15" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.15.tgz#7dcb394e69cb47e4dc8a5960dd58b1a273d07f5d" + integrity sha512-KXPY69MWw79QJkyvUYb2ex/OgnN/8N/Aw5UDPlgoRtoEfcBqfeLodPr42UojV3NdkoO4u10NXQdamWm1YEzSKw== + +"@esbuild/linux-riscv64@0.18.15": + version "0.18.15" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.15.tgz#fdfb9cf23b50d33112315e3194b9e16f7abf6c30" + integrity sha512-komK3NEAeeGRnvFEjX1SfVg6EmkfIi5aKzevdvJqMydYr9N+pRQK0PGJXk+bhoPZwOUgLO4l99FZmLGk/L1jWg== + +"@esbuild/linux-s390x@0.18.15": + version "0.18.15" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.18.15.tgz#ce608d95989a502878d7cb1167df791e45268011" + integrity sha512-632T5Ts6gQ2WiMLWRRyeflPAm44u2E/s/TJvn+BP6M5mnHSk93cieaypj3VSMYO2ePTCRqAFXtuYi1yv8uZJNA== + +"@esbuild/linux-x64@0.18.15": + version "0.18.15" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.18.15.tgz#49bbba5607702709f63b41906b4f1bcc44cf2f8e" + integrity sha512-MsHtX0NgvRHsoOtYkuxyk4Vkmvk3PLRWfA4okK7c+6dT0Fu4SUqXAr9y4Q3d8vUf1VWWb6YutpL4XNe400iQ1g== + +"@esbuild/netbsd-x64@0.18.15": + version "0.18.15" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.15.tgz#08b5ccaf027c7e2174b9a19c29bebfe59dce1cfb" + integrity sha512-djST6s+jQiwxMIVQ5rlt24JFIAr4uwUnzceuFL7BQT4CbrRtqBPueS4GjXSiIpmwVri1Icj/9pFRJ7/aScvT+A== + +"@esbuild/openbsd-x64@0.18.15": + version "0.18.15" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.15.tgz#38ec4223ebab562f0a89ffe20a40f05d500f89f0" + integrity sha512-naeRhUIvhsgeounjkF5mvrNAVMGAm6EJWiabskeE5yOeBbLp7T89tAEw0j5Jm/CZAwyLe3c67zyCWH6fsBLCpw== + +"@esbuild/sunos-x64@0.18.15": + version "0.18.15" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.18.15.tgz#dbbebf641957a54b77f39ca9b10b0b38586799ba" + integrity sha512-qkT2+WxyKbNIKV1AEhI8QiSIgTHMcRctzSaa/I3kVgMS5dl3fOeoqkb7pW76KwxHoriImhx7Mg3TwN/auMDsyQ== + +"@esbuild/win32-arm64@0.18.15": + version "0.18.15" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.18.15.tgz#7f15fe5d14b9b24eb18ca211ad92e0f5df92a18b" + integrity sha512-HC4/feP+pB2Vb+cMPUjAnFyERs+HJN7E6KaeBlFdBv799MhD+aPJlfi/yk36SED58J9TPwI8MAcVpJgej4ud0A== + +"@esbuild/win32-ia32@0.18.15": + version "0.18.15" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.18.15.tgz#a6609735a4a5e8fbdeb045720bc8be46825566fa" + integrity sha512-ovjwoRXI+gf52EVF60u9sSDj7myPixPxqzD5CmkEUmvs+W9Xd0iqISVBQn8xcx4ciIaIVlWCuTbYDOXOnOL44Q== + +"@esbuild/win32-x64@0.18.15": + version "0.18.15" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.18.15.tgz#41ee66253566124cc44bce1b4c760a87d9f5bf1d" + integrity sha512-imUxH9a3WJARyAvrG7srLyiK73XdX83NXQkjKvQ+7vPh3ZxoLrzvPkQKKw2DwZ+RV2ZB6vBfNHP8XScAmQC3aA== + "@eslint-community/eslint-utils@^4.2.0": version "4.2.0" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.2.0.tgz#a831e6e468b4b2b5ae42bf658bea015bf10bc518" @@ -1695,6 +1810,13 @@ consola "^2.15.0" node-fetch "^2.6.1" +"@originjs/vite-plugin-commonjs@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@originjs/vite-plugin-commonjs/-/vite-plugin-commonjs-1.0.3.tgz#2e3fb11ec78847da9422b79c103953f94d667f09" + integrity sha512-KuEXeGPptM2lyxdIEJ4R11+5ztipHoE7hy8ClZt3PYaOVQ/pyngd2alaSrPnwyFeOW1UagRBaQ752aA1dTMdOQ== + dependencies: + esbuild "^0.14.14" + "@pkgjs/parseargs@^0.11.0": version "0.11.0" resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" @@ -1755,6 +1877,23 @@ dependencies: type-fest "^2.0.0" +"@rollup/plugin-graphql@^2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@rollup/plugin-graphql/-/plugin-graphql-2.0.3.tgz#35fea077e225e2982ce8483dd6c381e8cca03aea" + integrity sha512-IuuELo+0t29adRuLVg8izBFiUXFSFw8BmezespscynRfvfXSOV0S7g8RzQt75VzP6KHHVmNmlAgz+8qlkLur3w== + dependencies: + "@rollup/pluginutils" "^5.0.1" + graphql-tag "^2.12.6" + +"@rollup/pluginutils@^5.0.1": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.0.2.tgz#012b8f53c71e4f6f9cb317e311df1404f56e7a33" + integrity sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA== + dependencies: + "@types/estree" "^1.0.0" + estree-walker "^2.0.2" + picomatch "^2.3.1" + "@sentry/core@5.30.0": version "5.30.0" resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.30.0.tgz#6b203664f69e75106ee8b5a2fe1d717379b331f3" @@ -2150,6 +2289,11 @@ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== +"@trysound/sax@0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" + integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== + "@types/aria-query@^4.2.0": version "4.2.0" resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.0.tgz#14264692a9d6e2fa4db3df5e56e94b5e25647ac0" @@ -2225,6 +2369,11 @@ dependencies: "@types/ms" "*" +"@types/estree@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2" + integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ== + "@types/events@*": version "1.2.0" resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" @@ -2567,6 +2716,11 @@ "@typescript-eslint/types" "5.38.0" eslint-visitor-keys "^3.3.0" +"@vitejs/plugin-vue2@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue2/-/plugin-vue2-1.1.2.tgz#891f0acc5a6a2b4886a74cb8d6359d42f19f968a" + integrity sha512-y6OEA+2UdJ0xrEQHodq20v9r3SpS62IOHrgN92JPLvVpNkhcissu7yvD5PXMzMESyazj0XNWGsc8UQk8+mVrjQ== + "@vue/apollo-components@^4.0.0-beta.4": version "4.0.0-beta.4" resolved "https://registry.yarnpkg.com/@vue/apollo-components/-/apollo-components-4.0.0-beta.4.tgz#cc2510cf22636c5b13fb42470578031631af6c51" @@ -2617,7 +2771,7 @@ postcss "^8.4.14" source-map "^0.6.1" -"@vue/compiler-sfc@^3.2.47": +"@vue/compiler-sfc@^3.2.20", "@vue/compiler-sfc@^3.2.47": version "3.2.47" resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.47.tgz#1bdc36f6cdc1643f72e2c397eb1a398f5004ad3d" integrity sha512-rog05W+2IFfxjMcFw10tM9+f7i/+FFpZJJ5XHX72NP9eC2uRD+42M3pYcQqDXVYoj74kHMSEdQ/WmCjt8JFksQ== @@ -3293,6 +3447,18 @@ atob@^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.8: + version "10.4.14" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.14.tgz#e28d49902f8e759dd25b153264e862df2705f79d" + integrity sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ== + dependencies: + browserslist "^4.21.5" + caniuse-lite "^1.0.30001464" + fraction.js "^4.2.0" + normalize-range "^0.1.2" + picocolors "^1.0.0" + postcss-value-parser "^4.2.0" + autosize@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/autosize/-/autosize-5.0.1.tgz#ed269b0fa9b7eb47627048a1bb3299e99e003a0f" @@ -3650,15 +3816,15 @@ browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" -browserslist@^4.20.2, browserslist@^4.20.3, browserslist@^4.21.3: - version "4.21.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.3.tgz#5df277694eb3c48bc5c4b05af3e8b7e09c5a6d1a" - integrity sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ== +browserslist@^4.20.2, browserslist@^4.20.3, browserslist@^4.21.3, browserslist@^4.21.5: + version "4.21.5" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7" + integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w== dependencies: - caniuse-lite "^1.0.30001370" - electron-to-chromium "^1.4.202" - node-releases "^2.0.6" - update-browserslist-db "^1.0.5" + caniuse-lite "^1.0.30001449" + electron-to-chromium "^1.4.284" + node-releases "^2.0.8" + update-browserslist-db "^1.0.10" bser@2.1.1: version "2.1.1" @@ -3835,7 +4001,7 @@ camelcase@^6.2.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001370: +caniuse-lite@^1.0.30001449, caniuse-lite@^1.0.30001464: version "1.0.30001478" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001478.tgz#0ef8a1cf8b16be47a0f9fc4ecfc952232724b32a" integrity sha512-gMhDyXGItTHipJj2ApIvR+iVB5hd0KP3svMWWXDvZOmjzJJassGLMfxRkQCSYgGd2gtdL/ReeiyvMSFD1Ss6Mw== @@ -4488,16 +4654,16 @@ css-loader@^2.1.1: postcss-value-parser "^3.3.0" schema-utils "^1.0.0" -css-select@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.1.2.tgz#8b52b6714ed3a80d8221ec971c543f3b12653286" - integrity sha512-nu5ye2Hg/4ISq4XqdLY2bEatAcLIdt3OYGFc9Tm9n7VSlFBcfRv0gBNksHRgSdUDQGtN3XrZ94ztW+NfzkFSUw== +css-select@^4.1.2, css-select@^4.1.3: + version "4.3.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b" + integrity sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ== dependencies: boolbase "^1.0.0" - css-what "^5.0.0" - domhandler "^4.2.0" - domutils "^2.6.0" - nth-check "^2.0.0" + css-what "^6.0.1" + domhandler "^4.3.1" + domutils "^2.8.0" + nth-check "^2.0.1" css-selector-parser@^1.3: version "1.3.0" @@ -4509,6 +4675,14 @@ css-shorthand-properties@^1.0.0: resolved "https://registry.yarnpkg.com/css-shorthand-properties/-/css-shorthand-properties-1.1.1.tgz#1c808e63553c283f289f2dd56fcee8f3337bd935" integrity sha512-Md+Juc7M3uOdbAFwOYlTrccIZ7oCFuzrhKYQjdeUEW/sE1hv17Jp/Bws+ReOPpGVBTYCBoYo+G17V5Qo8QQ75A== +css-tree@^1.1.2, css-tree@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" + integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== + dependencies: + mdn-data "2.0.14" + source-map "^0.6.1" + css-tree@^2.0.1: version "2.1.0" resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.1.0.tgz#170e27ccf94e7c5facb183765c25898be843d1d2" @@ -4531,6 +4705,11 @@ css-what@^5.0.0: resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.1.0.tgz#3f7b707aadf633baf62c2ceb8579b545bb40f7fe" integrity sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw== +css-what@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" + integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== + cssesc@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" @@ -4541,6 +4720,13 @@ cssfontparser@^1.2.1: resolved "https://registry.yarnpkg.com/cssfontparser/-/cssfontparser-1.2.1.tgz#f4022fc8f9700c68029d542084afbaf425a3f3e3" integrity sha1-9AIvyPlwDGgCnVQghK+69CWj8+M= +csso@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" + integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== + dependencies: + css-tree "^1.1.2" + cssom@^0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.5.0.tgz#d254fa92cd8b6fbd83811b9fbaed34663cc17c36" @@ -5430,10 +5616,10 @@ domexception@^4.0.0: dependencies: webidl-conversions "^7.0.0" -domhandler@^4.0.0, domhandler@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.2.0.tgz#f9768a5f034be60a89a27c2e4d0f74eba0d8b059" - integrity sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA== +domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c" + integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ== dependencies: domelementtype "^2.2.0" @@ -5447,10 +5633,10 @@ dompurify@2.4.5, dompurify@^2.4.5: resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.4.5.tgz#0e89a27601f0bad978f9a924e7a05d5d2cccdd87" integrity sha512-jggCCd+8Iqp4Tsz0nIvpcb22InKEBrGz5dw3EQJMs8HPJDsKbFIO3STYtAvCfDx26Muevn1MHVI0XxjgFfmiSA== -domutils@^2.5.2, domutils@^2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.6.0.tgz#2e15c04185d43fb16ae7057cb76433c6edb938b7" - integrity sha512-y0BezHuy4MDYxh6OvolXYsH+1EMGmFbwv5FKW7ovwMG6zTPWqNPq3WF9ayZssFq+UlKdffGLbOEaghNdaOm1WA== +domutils@^2.5.2, domutils@^2.6.0, domutils@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" + integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== dependencies: dom-serializer "^1.0.1" domelementtype "^2.2.0" @@ -5509,10 +5695,10 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -electron-to-chromium@^1.4.202: - version "1.4.230" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.230.tgz#666909fdf5765acb1348b69752ee9955dc1664b7" - integrity sha512-3pwjAK0qHSDN9+YAF4fJknsSruP7mpjdWzUSruIJD/JCH77pEh0SorEyb3xVaKkfwk2tzjOt2D8scJ0KAdfXLA== +electron-to-chromium@^1.4.284: + version "1.4.335" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.335.tgz#69c08baa608bbb58e290d83320190fa82c835efe" + integrity sha512-l/eowQqTnrq3gu+WSrdfkhfNHnPgYqlKAwxz7MTOj6mom19vpEDHNXl6dxDxyTiYuhemydprKr/HCrHfgk+OfQ== elkjs@^0.8.2: version "0.8.2" @@ -5698,6 +5884,161 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +esbuild-android-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.14.54.tgz#505f41832884313bbaffb27704b8bcaa2d8616be" + integrity sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ== + +esbuild-android-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.54.tgz#8ce69d7caba49646e009968fe5754a21a9871771" + integrity sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg== + +esbuild-darwin-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.54.tgz#24ba67b9a8cb890a3c08d9018f887cc221cdda25" + integrity sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug== + +esbuild-darwin-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.54.tgz#3f7cdb78888ee05e488d250a2bdaab1fa671bf73" + integrity sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw== + +esbuild-freebsd-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.54.tgz#09250f997a56ed4650f3e1979c905ffc40bbe94d" + integrity sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg== + +esbuild-freebsd-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.54.tgz#bafb46ed04fc5f97cbdb016d86947a79579f8e48" + integrity sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q== + +esbuild-linux-32@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.54.tgz#e2a8c4a8efdc355405325033fcebeb941f781fe5" + integrity sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw== + +esbuild-linux-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.54.tgz#de5fdba1c95666cf72369f52b40b03be71226652" + integrity sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg== + +esbuild-linux-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.54.tgz#dae4cd42ae9787468b6a5c158da4c84e83b0ce8b" + integrity sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig== + +esbuild-linux-arm@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.54.tgz#a2c1dff6d0f21dbe8fc6998a122675533ddfcd59" + integrity sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw== + +esbuild-linux-mips64le@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.54.tgz#d9918e9e4cb972f8d6dae8e8655bf9ee131eda34" + integrity sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw== + +esbuild-linux-ppc64le@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.54.tgz#3f9a0f6d41073fb1a640680845c7de52995f137e" + integrity sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ== + +esbuild-linux-riscv64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.54.tgz#618853c028178a61837bc799d2013d4695e451c8" + integrity sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg== + +esbuild-linux-s390x@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.54.tgz#d1885c4c5a76bbb5a0fe182e2c8c60eb9e29f2a6" + integrity sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA== + +esbuild-netbsd-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.54.tgz#69ae917a2ff241b7df1dbf22baf04bd330349e81" + integrity sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w== + +esbuild-openbsd-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.54.tgz#db4c8495287a350a6790de22edea247a57c5d47b" + integrity sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw== + +esbuild-sunos-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.54.tgz#54287ee3da73d3844b721c21bc80c1dc7e1bf7da" + integrity sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw== + +esbuild-windows-32@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.54.tgz#f8aaf9a5667630b40f0fb3aa37bf01bbd340ce31" + integrity sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w== + +esbuild-windows-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.54.tgz#bf54b51bd3e9b0f1886ffdb224a4176031ea0af4" + integrity sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ== + +esbuild-windows-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.54.tgz#937d15675a15e4b0e4fafdbaa3a01a776a2be982" + integrity sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg== + +esbuild@^0.14.14: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.54.tgz#8b44dcf2b0f1a66fc22459943dccf477535e9aa2" + integrity sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA== + optionalDependencies: + "@esbuild/linux-loong64" "0.14.54" + esbuild-android-64 "0.14.54" + esbuild-android-arm64 "0.14.54" + esbuild-darwin-64 "0.14.54" + esbuild-darwin-arm64 "0.14.54" + esbuild-freebsd-64 "0.14.54" + esbuild-freebsd-arm64 "0.14.54" + esbuild-linux-32 "0.14.54" + esbuild-linux-64 "0.14.54" + esbuild-linux-arm "0.14.54" + esbuild-linux-arm64 "0.14.54" + esbuild-linux-mips64le "0.14.54" + esbuild-linux-ppc64le "0.14.54" + esbuild-linux-riscv64 "0.14.54" + esbuild-linux-s390x "0.14.54" + esbuild-netbsd-64 "0.14.54" + esbuild-openbsd-64 "0.14.54" + esbuild-sunos-64 "0.14.54" + esbuild-windows-32 "0.14.54" + esbuild-windows-64 "0.14.54" + esbuild-windows-arm64 "0.14.54" + +esbuild@^0.18.10: + version "0.18.15" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.18.15.tgz#5b5c1a22e608afd5675f82ad466c4d2cfd723f85" + integrity sha512-3WOOLhrvuTGPRzQPU6waSDWrDTnQriia72McWcn6UCi43GhCHrXH4S59hKMeez+IITmdUuUyvbU9JIp+t3xlPQ== + optionalDependencies: + "@esbuild/android-arm" "0.18.15" + "@esbuild/android-arm64" "0.18.15" + "@esbuild/android-x64" "0.18.15" + "@esbuild/darwin-arm64" "0.18.15" + "@esbuild/darwin-x64" "0.18.15" + "@esbuild/freebsd-arm64" "0.18.15" + "@esbuild/freebsd-x64" "0.18.15" + "@esbuild/linux-arm" "0.18.15" + "@esbuild/linux-arm64" "0.18.15" + "@esbuild/linux-ia32" "0.18.15" + "@esbuild/linux-loong64" "0.18.15" + "@esbuild/linux-mips64el" "0.18.15" + "@esbuild/linux-ppc64" "0.18.15" + "@esbuild/linux-riscv64" "0.18.15" + "@esbuild/linux-s390x" "0.18.15" + "@esbuild/linux-x64" "0.18.15" + "@esbuild/netbsd-x64" "0.18.15" + "@esbuild/openbsd-x64" "0.18.15" + "@esbuild/sunos-x64" "0.18.15" + "@esbuild/win32-arm64" "0.18.15" + "@esbuild/win32-ia32" "0.18.15" + "@esbuild/win32-x64" "0.18.15" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -6435,6 +6776,11 @@ forwarded@0.2.0: resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== +fraction.js@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950" + integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== + fragment-cache@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" @@ -6775,7 +7121,7 @@ graphql-sse@^1.0.1: resolved "https://registry.yarnpkg.com/graphql-sse/-/graphql-sse-1.0.4.tgz#051598b0e06c225327aac659f19fcc18bcaa0191" integrity sha512-oB43ifRcEdElgep9jTP9qsj5cJ7Ny/1tAFyIl1W3A0hXRRg/P71tUHzMFBrRkEsJ9IA7MTp+RKSJfh52QR6PBQ== -graphql-tag@^2.11.0, graphql-tag@^2.12.3: +graphql-tag@^2.11.0, graphql-tag@^2.12.3, graphql-tag@^2.12.6: version "2.12.6" resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.12.6.tgz#d441a569c1d2537ef10ca3d1633b48725329b5f1" integrity sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg== @@ -8447,9 +8793,9 @@ loader-runner@^4.1.0: integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== loader-utils@^1.0.0, loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" - integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== + version "1.4.2" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.2.tgz#29a957f3a63973883eb684f10ffd3d151fec01a3" + integrity sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg== dependencies: big.js "^5.2.2" emojis-list "^3.0.0" @@ -8953,6 +9299,11 @@ mdast-util-to-string@^3.0.0, mdast-util-to-string@^3.1.0: resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-3.1.0.tgz#56c506d065fbf769515235e577b5a261552d56e9" integrity sha512-n4Vypz/DZgwo0iMHLQL49dJzlp7YtAJP+N07MZHpjPf/5XJuHUWstviF4Mn2jEiR/GNmtnRRqnwsXExk3igfFA== +mdn-data@2.0.14: + version "2.0.14" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" + integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== + mdn-data@2.0.27: version "2.0.27" resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.27.tgz#1710baa7b0db8176d3b3d565ccb7915fc69525ab" @@ -9683,10 +10034,10 @@ multicast-dns@^7.2.4: dns-packet "^5.2.2" thunky "^1.0.2" -nanoid@^3.3.4: - version "3.3.4" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" - integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== +nanoid@^3.3.4, nanoid@^3.3.6: + version "3.3.6" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" + integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== nanomatch@^1.2.9: version "1.2.13" @@ -9776,10 +10127,10 @@ node-libs-browser@^2.2.1: util "^0.11.0" vm-browserify "^1.0.1" -node-releases@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" - integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== +node-releases@^2.0.8: + version "2.0.10" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.10.tgz#c311ebae3b6a148c89b1813fd7c4d3c024ef537f" + integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== nodemon@^2.0.19: version "2.0.19" @@ -9848,6 +10199,11 @@ normalize-path@^3.0.0, normalize-path@~3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== + npm-run-path@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" @@ -9855,7 +10211,7 @@ npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" -nth-check@^2.0.0, nth-check@^2.0.1: +nth-check@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.1.tgz#2efe162f5c3da06a28959fbd3db75dbeea9f0fc2" integrity sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w== @@ -10418,7 +10774,7 @@ postcss-value-parser@^4.1.0, 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.4.14, postcss@^8.1.10, postcss@^8.2.1, postcss@^8.4.14: +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== @@ -10435,6 +10791,15 @@ postcss@^7.0.14, postcss@^7.0.36, postcss@^7.0.5, postcss@^7.0.6: picocolors "^0.2.1" source-map "^0.6.1" +postcss@^8.1.10, postcss@^8.2.1, postcss@^8.4.14, postcss@^8.4.27: + version "8.4.27" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.27.tgz#234d7e4b72e34ba5a92c29636734349e0d9c3057" + integrity sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ== + dependencies: + nanoid "^3.3.6" + picocolors "^1.0.0" + source-map-js "^1.0.2" + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -11197,6 +11562,13 @@ robust-predicates@^3.0.0: resolved "https://registry.yarnpkg.com/robust-predicates/-/robust-predicates-3.0.1.tgz#ecde075044f7f30118682bd9fb3f123109577f9a" integrity sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g== +rollup@^3.27.1: + version "3.27.2" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.27.2.tgz#59adc973504408289be89e5978e938ce852c9520" + integrity sha512-YGwmHf7h2oUHkVBT248x0yt6vZkYQ3/rvE5iQuVBh3WO8GcJ6BNeOkpoX1yMHIiBm18EMLjBPIoUDkhgnyxGOQ== + optionalDependencies: + fsevents "~2.3.2" + rope-sequence@^1.3.0: version "1.3.3" resolved "https://registry.yarnpkg.com/rope-sequence/-/rope-sequence-1.3.3.tgz#3f67fc106288b84b71532b4a5fd9d4881e4457f0" @@ -11803,6 +12175,11 @@ ssri@^8.0.0: dependencies: minipass "^3.1.1" +stable@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" + integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== + stack-utils@^2.0.3: version "2.0.5" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" @@ -12118,6 +12495,19 @@ svg-tags@^1.0.0: resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764" integrity sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q= +svgo@^2.7.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.8.0.tgz#4ff80cce6710dc2795f0c7c74101e6764cfccd24" + integrity sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg== + dependencies: + "@trysound/sax" "0.2.0" + commander "^7.2.0" + css-select "^4.1.3" + css-tree "^1.1.3" + csso "^4.2.0" + picocolors "^1.0.0" + stable "^0.1.8" + swagger-cli@^4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/swagger-cli/-/swagger-cli-4.0.4.tgz#c3f0b94277073c776b9bcc3ae7507b372f3ff414" @@ -12775,10 +13165,10 @@ unset-value@^1.0.0: has-value "^0.3.1" isobject "^3.0.0" -update-browserslist-db@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz#be06a5eedd62f107b7c19eb5bcefb194411abf38" - integrity sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q== +update-browserslist-db@^1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" + integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== dependencies: escalade "^3.1.1" picocolors "^1.0.0" @@ -12939,6 +13329,33 @@ visibilityjs@^1.2.4: resolved "https://registry.yarnpkg.com/visibilityjs/-/visibilityjs-1.2.4.tgz#bff8663da62c8c10ad4ee5ae6a1ae6fac4259d63" integrity sha1-v/hmPaYsjBCtTuWuahrm+sQlnWM= +vite-plugin-ruby@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/vite-plugin-ruby/-/vite-plugin-ruby-3.2.2.tgz#a174bc435b11350cfcb1b976342ca740d0bcaed2" + integrity sha512-cuHG1MajRWPR8YdfF6lvgsQRnKFEBRwZF//asFbRiI1psacxB5aPlHSvYZYxAu5IflrAa0MdR0HxEq+g98M3iQ== + dependencies: + debug "^4.3.4" + fast-glob "^3.2.12" + +vite-svg-loader@^3.4.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/vite-svg-loader/-/vite-svg-loader-3.6.0.tgz#71d246cba5e808c7f183a2a56a9dde6856bb0c92" + integrity sha512-bZJffcgCREW57kNkgMhuNqeDznWXyQwJ3wKrRhHLMMzwDnP5jr3vXW3cqsmquRR7VTP5mLdKj1/zzPPooGUuPw== + dependencies: + "@vue/compiler-sfc" "^3.2.20" + svgo "^2.7.0" + +vite@^4.4.9: + version "4.4.9" + resolved "https://registry.yarnpkg.com/vite/-/vite-4.4.9.tgz#1402423f1a2f8d66fd8d15e351127c7236d29d3d" + integrity sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA== + dependencies: + esbuild "^0.18.10" + postcss "^8.4.27" + rollup "^3.27.1" + optionalDependencies: + fsevents "~2.3.2" + vm-browserify@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.0.tgz#bd76d6a23323e2ca8ffa12028dc04559c75f9019"