diff --git a/app/assets/javascripts/design_management/components/design_notes/design_note.vue b/app/assets/javascripts/design_management/components/design_notes/design_note.vue index 38081c99e72..2162c93d3f9 100644 --- a/app/assets/javascripts/design_management/components/design_notes/design_note.vue +++ b/app/assets/javascripts/design_management/components/design_notes/design_note.vue @@ -15,9 +15,11 @@ import { getIdFromGraphQLId, convertToGraphQLId } from '~/graphql_shared/utils'; import { TYPENAME_USER } from '~/graphql_shared/constants'; import { __ } from '~/locale'; import { setUrlFragment } from '~/lib/utils/url_utility'; +import ImportedBadge from '~/vue_shared/components/imported_badge.vue'; import TimelineEntryItem from '~/vue_shared/components/notes/timeline_entry_item.vue'; import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; import EmojiPicker from '~/emoji/components/picker.vue'; +import { TYPE_COMMENT } from '~/import/constants'; import getDesignQuery from '../../graphql/queries/get_design.query.graphql'; import updateNoteMutation from '../../graphql/mutations/update_note.mutation.graphql'; import designNoteAwardEmojiToggleMutation from '../../graphql/mutations/design_note_award_emoji_toggle.mutation.graphql'; @@ -42,6 +44,7 @@ export default { GlButton, GlDisclosureDropdown, GlLink, + ImportedBadge, TimeAgoTooltip, TimelineEntryItem, }, @@ -124,6 +127,9 @@ export default { isEditingAndHasPermissions() { return !this.isEditing && this.adminPermissions; }, + isImported() { + return this.note.imported; + }, adminPermissions() { return this.note.userPermissions.adminNote; }, @@ -261,6 +267,7 @@ export default { }, }, updateNoteMutation, + TYPE_COMMENT, }; @@ -294,11 +301,12 @@ export default {
|
okay.
wysiwyg: |- -+
okay. @@ -1688,7 +1688,7 @@ foo |
+
|
+
- |
foo | bar |
|---|---|
baz | bim |
foo | bar |
|---|---|
baz | bim |
abc | defghi |
|---|---|
bar | baz |
abc | defghi |
|---|---|
bar | baz |
f|oo |
|---|
b |
b | im |
f|oo |
|---|
b |
b | im |
abc | def |
|---|---|
bar | baz |
abc | def |
|---|---|
bar | baz |
04_10_00__leaf_blocks__tables_extension__005: canonical: | @@ -2697,7 +2697,7 @@bar
bar
wysiwyg: |- -abc | def |
|---|---|
bar | baz |
bar |
abc | def |
|---|---|
bar | baz |
bar |
bar
04_10_00__leaf_blocks__tables_extension__006: canonical: | @@ -2752,7 +2752,7 @@ wysiwyg: |- -abc | def |
|---|---|
bar | |
bar | baz |
abc | def |
|---|---|
bar | |
bar | baz |
abc | def |
|---|
abc | def |
|---|
@@ -8519,7 +8519,7 @@content after table
wysiwyg: |- -+
header
header
codecell with bold
strikecell with italic
header
header
codecell with bold
strikecell with italic
content after table
08_04_49__gitlab_internal_extension_markdown__migrated_golden_master_examples__table_of_contents__001: canonical: | @@ -8813,7 +8813,7 @@ wysiwyg: |- -+
a
b
09_04_00__gfm_undocumented_extensions_and_more_robust_test__task_lists__001: canonical: |
a
b
diff --git a/lib/api/ci/jobs.rb b/lib/api/ci/jobs.rb index 4794c8d7218..656ee8d2909 100644 --- a/lib/api/ci/jobs.rb +++ b/lib/api/ci/jobs.rb @@ -55,12 +55,7 @@ module API builds = user_project.builds.order(id: :desc) builds = filter_builds(builds, params[:scope]) - - builds = builds.preload( - :job_artifacts_archive, :job_artifacts, :runner, :tags, :runner_manager, :metadata, - pipeline: :project, - user: [:user_preference, :user_detail, :followees] - ) + builds = builds.eager_load_for_api present paginate_with_strategies(builds, user_project, paginator_params: { without_count: true }), with: Entities::Ci::Job end diff --git a/lib/api/entities/project.rb b/lib/api/entities/project.rb index 50074ca10d9..a42574d3c92 100644 --- a/lib/api/entities/project.rb +++ b/lib/api/entities/project.rb @@ -41,87 +41,78 @@ module API end end - expose :packages_enabled, documentation: { type: 'boolean' } expose :empty_repo?, as: :empty_repo, documentation: { type: 'boolean' } expose :archived?, as: :archived, documentation: { type: 'boolean' } expose :visibility, documentation: { type: 'string', example: 'public' } expose :owner, using: Entities::UserBasic, unless: ->(project, options) { project.group } - expose :resolve_outdated_diff_discussions, documentation: { type: 'boolean' } - expose :container_expiration_policy, - using: Entities::ContainerExpirationPolicy, - if: ->(project, _) { project.container_expiration_policy } - expose :repository_object_format, documentation: { type: 'string', example: 'sha1' } - - # Expose old field names with the new permissions methods to keep API compatible - # TODO: remove in API v5, replaced by *_access_level - expose(:issues_enabled, documentation: { type: 'boolean' }) { |project, options| project.feature_available?(:issues, options[:current_user]) } - expose(:merge_requests_enabled, documentation: { type: 'boolean' }) { |project, options| project.feature_available?(:merge_requests, options[:current_user]) } - expose(:wiki_enabled, documentation: { type: 'boolean' }) { |project, options| project.feature_available?(:wiki, options[:current_user]) } - expose(:jobs_enabled, documentation: { type: 'boolean' }) { |project, options| project.feature_available?(:builds, options[:current_user]) } - expose(:snippets_enabled, documentation: { type: 'boolean' }) { |project, options| project.feature_available?(:snippets, options[:current_user]) } - expose(:container_registry_enabled, documentation: { type: 'boolean' }) { |project, options| project.feature_available?(:container_registry, options[:current_user]) } - expose :service_desk_enabled, documentation: { type: 'boolean' } - expose :service_desk_address, documentation: { type: 'string', example: 'address@example.com' }, if: ->(project, options) do - Ability.allowed?(options[:current_user], :admin_issue, project) - end + expose :open_issues_count, documentation: { type: 'integer', example: 1 }, if: lambda { |project, options| project.feature_available?(:issues, options[:current_user]) } + expose :description_html, documentation: { type: 'string' } + expose :updated_at, documentation: { type: 'dateTime', example: '2020-05-07T04:27:17.016Z' } expose(:can_create_merge_request_in, documentation: { type: 'boolean' }) do |project, options| Ability.allowed?(options[:current_user], :create_merge_request_in, project) end - expose(:issues_access_level, documentation: { type: 'string', example: 'enabled' }) { |project, options| project_feature_string_access_level(project, :issues) } - expose(:repository_access_level, documentation: { type: 'string', example: 'enabled' }) { |project, options| project_feature_string_access_level(project, :repository) } - expose(:merge_requests_access_level, documentation: { type: 'string', example: 'enabled' }) { |project, options| project_feature_string_access_level(project, :merge_requests) } - expose(:forking_access_level, documentation: { type: 'string', example: 'enabled' }) { |project, options| project_feature_string_access_level(project, :forking) } - expose(:wiki_access_level, documentation: { type: 'string', example: 'enabled' }) { |project, options| project_feature_string_access_level(project, :wiki) } - expose(:builds_access_level, documentation: { type: 'string', example: 'enabled' }) { |project, options| project_feature_string_access_level(project, :builds) } - expose(:snippets_access_level, documentation: { type: 'string', example: 'enabled' }) { |project, options| project_feature_string_access_level(project, :snippets) } - expose(:pages_access_level, documentation: { type: 'string', example: 'enabled' }) { |project, options| project_feature_string_access_level(project, :pages) } - expose(:analytics_access_level, documentation: { type: 'string', example: 'enabled' }) { |project, options| project_feature_string_access_level(project, :analytics) } - expose(:container_registry_access_level, documentation: { type: 'string', example: 'enabled' }) { |project, options| project_feature_string_access_level(project, :container_registry) } - expose(:security_and_compliance_access_level, documentation: { type: 'string', example: 'enabled' }) { |project, options| project_feature_string_access_level(project, :security_and_compliance) } - expose(:releases_access_level, documentation: { type: 'string', example: 'enabled' }) { |project, options| project_feature_string_access_level(project, :releases) } - expose(:environments_access_level, documentation: { type: 'string', example: 'enabled' }) { |project, options| project_feature_string_access_level(project, :environments) } - expose(:feature_flags_access_level, documentation: { type: 'string', example: 'enabled' }) { |project, options| project_feature_string_access_level(project, :feature_flags) } - expose(:infrastructure_access_level, documentation: { type: 'string', example: 'enabled' }) { |project, options| project_feature_string_access_level(project, :infrastructure) } - expose(:monitor_access_level, documentation: { type: 'string', example: 'enabled' }) { |project, options| project_feature_string_access_level(project, :monitor) } - expose(:model_experiments_access_level, documentation: { type: 'string', example: 'enabled' }) { |project, options| project_feature_string_access_level(project, :model_experiments) } - expose(:model_registry_access_level, documentation: { type: 'string', example: 'enabled' }) { |project, options| project_feature_string_access_level(project, :model_registry) } - - expose(:emails_disabled, documentation: { type: 'boolean' }) { |project, options| project.emails_disabled? } - expose :emails_enabled, documentation: { type: 'boolean' } - - expose :shared_runners_enabled, documentation: { type: 'boolean' } - expose :lfs_enabled?, as: :lfs_enabled, documentation: { type: 'boolean' } - expose :creator_id, documentation: { type: 'integer', example: 1 } expose :forked_from_project, using: Entities::BasicProjectDetails, if: ->(project, options) do project.forked? && Ability.allowed?(options[:current_user], :read_project, project.forked_from_project) end + + expose :statistics, using: 'API::Entities::ProjectStatistics', if: ->(project, options) { + options[:statistics] && Ability.allowed?(options[:current_user], :read_statistics, project) + } + + expose :ci_config_path, documentation: { type: 'string', example: '' }, if: ->(project, options) { + Ability.allowed?(options[:current_user], :read_code, project) + } + expose :mr_default_target_self, if: ->(project) { project.forked? }, documentation: { type: 'boolean' } - expose :import_url, documentation: { type: 'string', example: 'https://gitlab.com/gitlab/gitlab.git' }, if: ->(project, options) { Ability.allowed?(options[:current_user], :admin_project, project) } do |project| - project[:import_url] - end - expose :import_type, documentation: { type: 'string', example: 'git' }, if: ->(project, options) { Ability.allowed?(options[:current_user], :admin_project, project) } - expose :import_status, documentation: { type: 'string', example: 'none' } - expose :import_error, documentation: { type: 'string', example: 'Import error' }, if: lambda { |_project, options| options[:user_can_admin_project] } do |project| - project.import_state&.last_error - end - expose :open_issues_count, documentation: { type: 'integer', example: 1 }, if: lambda { |project, options| project.feature_available?(:issues, options[:current_user]) } - expose :description_html, documentation: { type: 'string' } - expose :updated_at, documentation: { type: 'dateTime', example: '2020-05-07T04:27:17.016Z' } + expose :shared_with_groups, documentation: { is_array: true } do |project, options| + user = options[:current_user] + + SharedGroupWithProject.represent(project.visible_group_links(for_user: user), options) + end + + expose :service_desk_address, documentation: { type: 'string', example: 'address@example.com' }, if: ->(project, options) do + Ability.allowed?(options[:current_user], :admin_issue, project) + end + + with_options if: ->(_, _) { user_can_admin_project? } do + expose :emails_disabled?, as: :emails_disabled, documentation: { type: 'boolean' } + expose :emails_enabled, documentation: { type: 'boolean' } + + expose :resolve_outdated_diff_discussions, documentation: { type: 'boolean' } + expose :container_expiration_policy, + using: Entities::ContainerExpirationPolicy, + if: ->(project, _) { project.container_expiration_policy } + expose :repository_object_format, documentation: { type: 'string', example: 'sha1' } + + expose :shared_runners_enabled, documentation: { type: 'boolean' } + expose :lfs_enabled?, as: :lfs_enabled, documentation: { type: 'boolean' } + expose :creator_id, documentation: { type: 'integer', example: 1 } + + expose :import_url, documentation: { type: 'string', example: 'https://gitlab.com/gitlab/gitlab.git' } do |project| + project[:import_url] + end + + expose :import_type, documentation: { type: 'string', example: 'git' } + expose :import_status, documentation: { type: 'string', example: 'none' } + expose :import_error, documentation: { type: 'string', example: 'Import error' } do |project| + project.import_state&.last_error + end - with_options if: ->(_, _) { Ability.allowed?(options[:current_user], :admin_project, project) } do - # CI/CD Settings expose :ci_default_git_depth, documentation: { type: 'integer', example: 20 } expose :ci_forward_deployment_enabled, documentation: { type: 'boolean' } expose :ci_forward_deployment_rollback_allowed, documentation: { type: 'boolean' } - expose(:ci_job_token_scope_enabled, documentation: { type: 'boolean' }) { |p, _| p.ci_outbound_job_token_scope_enabled? } + + expose :ci_outbound_job_token_scope_enabled?, as: :ci_job_token_scope_enabled, documentation: { type: 'boolean' } + expose :ci_separated_caches, documentation: { type: 'boolean' } expose :ci_allow_fork_pipelines_to_run_in_parent_project, documentation: { type: 'boolean' } - expose :build_git_strategy, documentation: { type: 'string', example: 'fetch' } do |project, options| + expose :build_git_strategy, documentation: { type: 'string', example: 'fetch' } do |project| project.build_allow_git_fetch ? 'fetch' : 'clone' end + expose :keep_latest_artifacts_available?, as: :keep_latest_artifact, documentation: { type: 'boolean' } expose :restrict_user_defined_variables, documentation: { type: 'boolean' } expose :runners_token, documentation: { type: 'string', example: 'b8547b1dc37721d05889db52fa2f02' } @@ -130,40 +121,133 @@ module API expose :auto_cancel_pending_pipelines, documentation: { type: 'string', example: 'enabled' } expose :build_timeout, documentation: { type: 'integer', example: 3600 } expose :auto_devops_enabled?, as: :auto_devops_enabled, documentation: { type: 'boolean' } - expose :auto_devops_deploy_strategy, documentation: { type: 'string', example: 'continuous' } do |project, options| + expose :auto_devops_deploy_strategy, documentation: { type: 'string', example: 'continuous' } do |project| project.auto_devops.nil? ? 'continuous' : project.auto_devops.deploy_strategy end + + expose :public_builds, as: :public_jobs, documentation: { type: 'boolean' } + + expose :only_allow_merge_if_pipeline_succeeds, documentation: { type: 'boolean' } + expose :allow_merge_on_skipped_pipeline, documentation: { type: 'boolean' } + expose :request_access_enabled, documentation: { type: 'boolean' } + expose :only_allow_merge_if_all_discussions_are_resolved, documentation: { type: 'boolean' } + expose :remove_source_branch_after_merge, documentation: { type: 'boolean' } + expose :printing_merge_request_link_enabled, documentation: { type: 'boolean' } + expose :merge_method, documentation: { type: 'string', example: 'merge' } + expose :squash_option, documentation: { type: 'string', example: 'default_off' } + expose :enforce_auth_checks_on_uploads, documentation: { type: 'boolean' } + expose :suggestion_commit_message, documentation: { type: 'string', example: 'Suggestion message' } + expose :merge_commit_template, documentation: { type: 'string', example: '%(title)' } + expose :squash_commit_template, documentation: { type: 'string', example: '%(source_branch)' } + expose :issue_branch_template, documentation: { type: 'string', example: '%(title)' } + + expose :warn_about_potentially_unwanted_characters, documentation: { type: 'boolean' } + + expose :autoclose_referenced_issues, documentation: { type: 'boolean' } + + # Expose old field names with the new permissions methods to keep API compatible + # TODO: remove in API v5, replaced by *_access_level + expose :packages_enabled, documentation: { type: 'boolean' } + expose :service_desk_enabled, documentation: { type: 'boolean' } + + expose :issues_enabled, documentation: { type: 'boolean' } do |project, options| + project.feature_available?(:issues, options[:current_user]) + end + + expose :merge_requests_enabled, documentation: { type: 'boolean' } do |project, options| + project.feature_available?(:merge_requests, options[:current_user]) + end + + expose :wiki_enabled, documentation: { type: 'boolean' } do |project, options| + project.feature_available?(:wiki, options[:current_user]) + end + + expose :jobs_enabled, documentation: { type: 'boolean' } do |project, options| + project.feature_available?(:builds, options[:current_user]) + end + + expose :snippets_enabled, documentation: { type: 'boolean' } do |project, options| + project.feature_available?(:snippets, options[:current_user]) + end + + expose :container_registry_enabled, documentation: { type: 'boolean' } do |project, options| + project.feature_available?(:container_registry, options[:current_user]) + end + + # Visibility, project features, permissions settings + expose :issues_access_level, documentation: { type: 'string', example: 'enabled' } do |project| + project_feature_string_access_level(project, :issues) + end + + expose :repository_access_level, documentation: { type: 'string', example: 'enabled' } do |project| + project_feature_string_access_level(project, :repository) + end + + expose :merge_requests_access_level, documentation: { type: 'string', example: 'enabled' } do |project| + project_feature_string_access_level(project, :merge_requests) + end + + expose :forking_access_level, documentation: { type: 'string', example: 'enabled' } do |project| + project_feature_string_access_level(project, :forking) + end + + expose :wiki_access_level, documentation: { type: 'string', example: 'enabled' } do |project| + project_feature_string_access_level(project, :wiki) + end + + expose :builds_access_level, documentation: { type: 'string', example: 'enabled' } do |project| + project_feature_string_access_level(project, :builds) + end + + expose :snippets_access_level, documentation: { type: 'string', example: 'enabled' } do |project| + project_feature_string_access_level(project, :snippets) + end + + expose :pages_access_level, documentation: { type: 'string', example: 'enabled' } do |project| + project_feature_string_access_level(project, :pages) + end + + expose :analytics_access_level, documentation: { type: 'string', example: 'enabled' } do |project| + project_feature_string_access_level(project, :analytics) + end + + expose :container_registry_access_level, documentation: { type: 'string', example: 'enabled' } do |project| + project_feature_string_access_level(project, :container_registry) + end + + expose :security_and_compliance_access_level, documentation: { type: 'string', example: 'enabled' } do |project| + project_feature_string_access_level(project, :security_and_compliance) + end + + expose :releases_access_level, documentation: { type: 'string', example: 'enabled' } do |project| + project_feature_string_access_level(project, :releases) + end + + expose :environments_access_level, documentation: { type: 'string', example: 'enabled' } do |project| + project_feature_string_access_level(project, :environments) + end + + expose :feature_flags_access_level, documentation: { type: 'string', example: 'enabled' } do |project| + project_feature_string_access_level(project, :feature_flags) + end + + expose :infrastructure_access_level, documentation: { type: 'string', example: 'enabled' } do |project| + project_feature_string_access_level(project, :infrastructure) + end + + expose :monitor_access_level, documentation: { type: 'string', example: 'enabled' } do |project| + project_feature_string_access_level(project, :monitor) + end + + expose :model_experiments_access_level, documentation: { type: 'string', example: 'enabled' } do |project| + project_feature_string_access_level(project, :model_experiments) + end + + expose :model_registry_access_level, documentation: { type: 'string', example: 'enabled' } do |project| + project_feature_string_access_level(project, :model_registry) + end end - expose :ci_config_path, documentation: { type: 'string', example: '' }, if: ->(project, options) { Ability.allowed?(options[:current_user], :read_code, project) } - expose :public_builds, as: :public_jobs, documentation: { type: 'boolean' } - - expose :shared_with_groups, documentation: { is_array: true } do |project, options| - user = options[:current_user] - - SharedGroupWithProject.represent(project.visible_group_links(for_user: user), options) - end - - expose :only_allow_merge_if_pipeline_succeeds, documentation: { type: 'boolean' } - expose :allow_merge_on_skipped_pipeline, documentation: { type: 'boolean' } - expose :request_access_enabled, documentation: { type: 'boolean' } - expose :only_allow_merge_if_all_discussions_are_resolved, documentation: { type: 'boolean' } - expose :remove_source_branch_after_merge, documentation: { type: 'boolean' } - expose :printing_merge_request_link_enabled, documentation: { type: 'boolean' } - expose :merge_method, documentation: { type: 'string', example: 'merge' } - expose :squash_option, documentation: { type: 'string', example: 'default_off' } - expose :enforce_auth_checks_on_uploads, documentation: { type: 'boolean' } - expose :suggestion_commit_message, documentation: { type: 'string', example: 'Suggestion message' } - expose :merge_commit_template, documentation: { type: 'string', example: '%(title)' } - expose :squash_commit_template, documentation: { type: 'string', example: '%(source_branch)' } - expose :issue_branch_template, documentation: { type: 'string', example: '%(title)' } - expose :statistics, using: 'API::Entities::ProjectStatistics', if: ->(project, options) { - options[:statistics] && Ability.allowed?(options[:current_user], :read_statistics, project) - } - expose :warn_about_potentially_unwanted_characters, documentation: { type: 'boolean' } - - expose :autoclose_referenced_issues, documentation: { type: 'boolean' } - # rubocop: disable CodeReuse/ActiveRecord def self.preload_resource(project) ActiveRecord::Associations::Preloader.new(records: [project], associations: { project_group_links: { group: :route } }).call @@ -200,6 +284,10 @@ module API def self.repositories_for_preload(projects_relation) super + projects_relation.map(&:forked_from_project).compact.map(&:repository) end + + def user_can_admin_project? + Ability.allowed?(options[:current_user], :admin_project, project) + end end end end diff --git a/lib/api/helpers/integrations_helpers.rb b/lib/api/helpers/integrations_helpers.rb index 7458b4e4234..6b83947dfc8 100644 --- a/lib/api/helpers/integrations_helpers.rb +++ b/lib/api/helpers/integrations_helpers.rb @@ -97,11 +97,11 @@ module API def self.integrations { - 'apple-app-store' => ::Integrations::AppleAppStore.api_fields, - 'asana' => ::Integrations::Asana.api_fields, - 'assembla' => ::Integrations::Assembla.api_fields, - 'bamboo' => ::Integrations::Bamboo.api_fields, - 'bugzilla' => ::Integrations::Bugzilla.api_fields, + 'apple-app-store' => ::Integrations::AppleAppStore.api_arguments, + 'asana' => ::Integrations::Asana.api_arguments, + 'assembla' => ::Integrations::Assembla.api_arguments, + 'bamboo' => ::Integrations::Bamboo.api_arguments, + 'bugzilla' => ::Integrations::Bugzilla.api_arguments, 'buildkite' => [ { required: true, @@ -122,9 +122,9 @@ module API desc: 'DEPRECATED: This parameter has no effect since SSL verification will always be enabled' } ], - 'campfire' => ::Integrations::Campfire.api_fields, - 'confluence' => ::Integrations::Confluence.api_fields, - 'custom-issue-tracker' => ::Integrations::CustomIssueTracker.api_fields, + 'campfire' => ::Integrations::Campfire.api_arguments, + 'confluence' => ::Integrations::Confluence.api_arguments, + 'custom-issue-tracker' => ::Integrations::CustomIssueTracker.api_arguments, 'datadog' => [ { required: true, @@ -169,9 +169,9 @@ module API desc: 'Custom tags in Datadog. Specify one tag per line in the format: "key:value\nkey2:value2"' } ], - 'diffblue-cover' => ::Integrations::DiffblueCover.api_fields, + 'diffblue-cover' => ::Integrations::DiffblueCover.api_arguments, 'discord' => [ - ::Integrations::Discord.api_fields, + ::Integrations::Discord.api_arguments, chat_notification_flags, chat_notification_channels ].flatten, @@ -221,12 +221,12 @@ module API desc: 'Branches for which notifications are to be sent' } ], - 'external-wiki' => ::Integrations::ExternalWiki.api_fields, + 'external-wiki' => ::Integrations::ExternalWiki.api_arguments, 'gitlab-slack-application' => [ - ::Integrations::GitlabSlackApplication.api_fields, + ::Integrations::GitlabSlackApplication.api_arguments, chat_notification_channels ].flatten, - 'google-play' => ::Integrations::GooglePlay.api_fields, + 'google-play' => ::Integrations::GooglePlay.api_arguments, 'hangouts-chat' => [ { required: true, @@ -241,7 +241,7 @@ module API desc: 'Branches for which notifications are to be sent' } ].flatten, - 'harbor' => ::Integrations::Harbor.api_fields, + 'harbor' => ::Integrations::Harbor.api_arguments, 'irker' => [ { required: true, @@ -380,7 +380,7 @@ module API desc: 'Enable comments inside Jira issues on each GitLab event (commit / merge request)' } ], - 'mattermost-slash-commands' => ::Integrations::MattermostSlashCommands.api_fields, + 'mattermost-slash-commands' => ::Integrations::MattermostSlashCommands.api_arguments, 'slack-slash-commands' => [ { required: true, @@ -409,7 +409,7 @@ module API desc: 'The server' } ], - 'phorge' => ::Integrations::Phorge.api_fields, + 'phorge' => ::Integrations::Phorge.api_arguments, 'pipelines-email' => [ { required: true, @@ -516,12 +516,12 @@ module API desc: 'The sound of the notification' } ], - 'redmine' => ::Integrations::Redmine.api_fields, - 'ewm' => ::Integrations::Ewm.api_fields, - 'youtrack' => ::Integrations::Youtrack.api_fields, - 'clickup' => ::Integrations::Clickup.api_fields, + 'redmine' => ::Integrations::Redmine.api_arguments, + 'ewm' => ::Integrations::Ewm.api_arguments, + 'youtrack' => ::Integrations::Youtrack.api_arguments, + 'clickup' => ::Integrations::Clickup.api_arguments, 'slack' => [ - ::Integrations::Slack.api_fields, + ::Integrations::Slack.api_arguments, chat_notification_channels ].flatten, 'microsoft-teams' => [ @@ -540,7 +540,7 @@ module API chat_notification_flags ].flatten, 'mattermost' => [ - ::Integrations::Mattermost.api_fields, + ::Integrations::Mattermost.api_arguments, chat_notification_channels ].flatten, 'teamcity' => [ @@ -616,7 +616,7 @@ module API desc: 'The Unify Circuit webhook. e.g. https://circuit.com/rest/v2/webhooks/incoming/…' } ].flatten, - 'webex-teams' => ::Integrations::WebexTeams.api_fields, + 'webex-teams' => ::Integrations::WebexTeams.api_arguments, 'zentao' => [ { required: true, @@ -643,7 +643,7 @@ module API desc: 'The product ID of ZenTao project' } ], - 'squash-tm' => ::Integrations::SquashTm.api_fields + 'squash-tm' => ::Integrations::SquashTm.api_arguments } end diff --git a/lib/api/integrations.rb b/lib/api/integrations.rb index a64bb569a3f..726054c424c 100644 --- a/lib/api/integrations.rb +++ b/lib/api/integrations.rb @@ -9,7 +9,7 @@ module API integration_classes = Helpers::IntegrationsHelpers.integration_classes if Gitlab.dev_or_test_env? - integrations['mock-ci'] = ::Integrations::MockCi.api_fields + integrations['mock-ci'] = ::Integrations::MockCi.api_arguments integrations['mock-monitoring'] = [] integration_classes += Helpers::IntegrationsHelpers.development_integration_classes @@ -30,8 +30,8 @@ module API end SLASH_COMMAND_INTEGRATIONS = { - 'mattermost-slash-commands' => ::Integrations::MattermostSlashCommands.api_fields, - 'slack-slash-commands' => ::Integrations::SlackSlashCommands.api_fields + 'mattermost-slash-commands' => ::Integrations::MattermostSlashCommands.api_arguments, + 'slack-slash-commands' => ::Integrations::SlackSlashCommands.api_arguments }.freeze helpers do diff --git a/lib/gitlab/internal_events.rb b/lib/gitlab/internal_events.rb index a941e758e31..d56d82ed9bd 100644 --- a/lib/gitlab/internal_events.rb +++ b/lib/gitlab/internal_events.rb @@ -30,8 +30,7 @@ module Gitlab project = kwargs[:project] kwargs[:namespace] ||= project.namespace if project - increase_total_counter(event_name) - increase_weekly_total_counter(event_name) + update_redis_values(event_name, additional_properties) update_unique_counters(event_name, kwargs) trigger_snowplow_event(event_name, category, additional_properties, kwargs) if send_snowplow_event @@ -54,6 +53,19 @@ module Gitlab nil end + def convert_event_selection_rule_to_path_part(event_selection_rule) + path = event_selection_rule[:name] + + if event_selection_rule[:filter].present? + filter = event_selection_rule[:filter] + sorted_filter_keys = filter.keys.sort + serialized_filter = sorted_filter_keys.map { |key| "#{key}:#{filter[key]}" }.join(',') + path = "#{path}-filter:[#{serialized_filter}]" + end + + path + end + private def validate_properties!(additional_properties, kwargs) @@ -87,16 +99,30 @@ module Gitlab end end - def increase_total_counter(event_name) - redis_counter_key = Gitlab::Usage::Metrics::Instrumentations::TotalCountMetric.redis_key(event_name) + def update_redis_values(event_name, additional_properties) + event_definition = Gitlab::Tracking::EventDefinition.find(event_name) - increment(redis_counter_key) - end + return unless event_definition - def increase_weekly_total_counter(event_name) - redis_counter_key = Gitlab::Usage::Metrics::Instrumentations::TotalCountMetric.redis_key(event_name, Date.today) + event_definition.event_selection_rules.each do |event_selection_rule| + matches_filter = event_selection_rule[:filter].all? do |property_name, value| + additional_properties[property_name] == value + end - increment(redis_counter_key, expiry: 6.weeks) + next unless matches_filter + + event_specific_part_of_path = convert_event_selection_rule_to_path_part(event_selection_rule) + + if event_selection_rule[:time_framed?] + redis_key = Gitlab::Usage::Metrics::Instrumentations::TotalCountMetric.redis_key( + event_specific_part_of_path, + Date.today + ) + increment(redis_key, expiry: 6.weeks) + else + increment(Gitlab::Usage::Metrics::Instrumentations::TotalCountMetric.redis_key(event_specific_part_of_path)) + end + end end def update_unique_counters(event_name, kwargs) diff --git a/lib/gitlab/tracking/event_definition.rb b/lib/gitlab/tracking/event_definition.rb index 0692c066097..fc5d909679d 100644 --- a/lib/gitlab/tracking/event_definition.rb +++ b/lib/gitlab/tracking/event_definition.rb @@ -12,10 +12,18 @@ module Gitlab attr_reader :attributes class << self + include Gitlab::Utils::StrongMemoize + def definitions @definitions ||= paths.flat_map { |glob_path| load_all_from_path(glob_path) } end + def find(event_name) + strong_memoize_with(:find, event_name) do + definitions.find { |definition| definition.attributes[:action] == event_name } + end + end + private def paths @@ -62,6 +70,31 @@ module Gitlab ERROR_MSG end end + + def event_selection_rules + @event_selection_rules ||= find_event_selection_rules + end + + private + + def find_event_selection_rules + result = [ + { name: attributes[:action], time_framed?: false, filter: {} }, + { name: attributes[:action], time_framed?: true, filter: {} } + ] + Gitlab::Usage::MetricDefinition.definitions.each_value do |metric_definition| + metric_definition.attributes[:events]&.each do |event_selection_rule| + if event_selection_rule[:name] == attributes[:action] + result << { + name: attributes[:action], + time_framed?: %w[7d 28d].include?(metric_definition.attributes[:time_frame]), + filter: event_selection_rule[:filter] || {} + } + end + end + end + result.uniq + end end end end diff --git a/lib/gitlab/usage/metrics/instrumentations/total_count_metric.rb b/lib/gitlab/usage/metrics/instrumentations/total_count_metric.rb index 9bf54be1905..3007de01d87 100644 --- a/lib/gitlab/usage/metrics/instrumentations/total_count_metric.rb +++ b/lib/gitlab/usage/metrics/instrumentations/total_count_metric.rb @@ -26,23 +26,18 @@ module Gitlab end def value - return total_value if time_frame == 'all' - - period_value - end - - private - - def total_value - event_names.sum do |event_name| - redis_usage_data do - total_count(self.class.redis_key(event_name)) - end + event_specific_part_of_paths = events.map do |event_selection_rule| + Gitlab::InternalEvents.convert_event_selection_rule_to_path_part(event_selection_rule) end - end - def period_value - keys = self.class.keys_for_aggregation(events: event_names, **time_constraint) + keys = if time_frame == 'all' + event_specific_part_of_paths.map do |event_specific_part_of_path| + self.class.redis_key(event_specific_part_of_path) + end + else + self.class.keys_for_aggregation(events: event_specific_part_of_paths, **time_constraint) + end + keys.sum do |key| redis_usage_data do total_count(key) diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 25a2b58fa22..221a5594cb7 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -21562,9 +21562,6 @@ msgstr "" msgid "Failed to delete custom emoji. Please try again." msgstr "" -msgid "Failed to delete model" -msgstr "" - msgid "Failed to deploy to" msgstr "" @@ -33120,9 +33117,6 @@ msgstr "" msgid "Modal|Close" msgstr "" -msgid "Model deleted but failed to remove associated packages" -msgstr "" - msgid "Model experiments" msgstr "" @@ -33132,9 +33126,6 @@ msgstr "" msgid "Model version not found" msgstr "" -msgid "Model was successfully deleted" -msgstr "" - msgid "ModelRegistry|Model registry" msgstr "" @@ -45437,7 +45428,10 @@ msgstr "" msgid "ScanExecutionPolicy|%{labelStart}File path:%{labelEnd} %{filePath}" msgstr "" -msgid "ScanExecutionPolicy|%{overrideSelector}into the %{boldStart}.gitlab-ci.yml%{boldEnd} with the following %{boldStart}pipeline execution file%{boldEnd} from %{projectSelector} And run with reference (Optional) %{refSelector}" +msgid "ScanExecutionPolicy|%{overrideSelector}into the %{boldStart}.gitlab-ci.yml%{boldEnd} with the following %{boldStart}pipeline execution file%{boldEnd} from %{projectSelector}" +msgstr "" + +msgid "ScanExecutionPolicy|%{overrideSelector}the %{boldStart}.gitlab-ci.yml%{boldEnd} with the following %{boldStart}pipeline execution file%{boldEnd} from %{projectSelector}" msgstr "" msgid "ScanExecutionPolicy|%{period} %{days} around %{time} %{timezoneLabel} %{timezone}" @@ -45482,6 +45476,9 @@ msgstr "" msgid "ScanExecutionPolicy|DAST site profiles" msgstr "" +msgid "ScanExecutionPolicy|File reference (Optional) %{refSelector}" +msgstr "" + msgid "ScanExecutionPolicy|If there are any conflicting variables with the local pipeline configuration (Ex, gitlab-ci.yml) then variables defined here will take precedence. %{linkStart}Learn more%{linkEnd}." msgstr "" @@ -45560,7 +45557,10 @@ msgstr "" msgid "ScanExecutionPolicy|Select timezone" msgstr "" -msgid "ScanExecutionPolicy|The content of this pipeline execution YAML file is included in the .gitlab-ci.yml file of the target project. All GitLab CI/CD features are supported." +msgid "ScanExecutionPolicy|The content of this pipeline execution YAML file is injected into the .gitlab-ci.yml file of the target project. All GitLab CI/CD features are supported." +msgstr "" + +msgid "ScanExecutionPolicy|The content of this pipeline execution YAML file overrides the .gitlab-ci.yml file of the target project. All GitLab CI/CD features are supported." msgstr "" msgid "ScanExecutionPolicy|The file at that project, ref, and path doesn't exist" diff --git a/package.json b/package.json index c50ddb24fff..d35faaf8a33 100644 --- a/package.json +++ b/package.json @@ -77,41 +77,41 @@ "@snowplow/browser-plugin-timezone": "^3.9.0", "@snowplow/browser-tracker": "^3.9.0", "@sourcegraph/code-host-integration": "0.0.95", - "@tiptap/core": "^2.1.14", - "@tiptap/extension-blockquote": "^2.1.14", - "@tiptap/extension-bold": "^2.1.14", - "@tiptap/extension-bubble-menu": "^2.1.14", - "@tiptap/extension-bullet-list": "^2.1.14", - "@tiptap/extension-code": "^2.1.14", - "@tiptap/extension-code-block": "^2.1.14", - "@tiptap/extension-code-block-lowlight": "^2.1.14", - "@tiptap/extension-document": "^2.1.14", - "@tiptap/extension-dropcursor": "^2.1.14", - "@tiptap/extension-gapcursor": "^2.1.14", - "@tiptap/extension-hard-break": "^2.1.14", - "@tiptap/extension-heading": "^2.1.14", - "@tiptap/extension-highlight": "^2.1.14", - "@tiptap/extension-history": "^2.1.14", - "@tiptap/extension-horizontal-rule": "^2.1.14", - "@tiptap/extension-image": "^2.1.14", - "@tiptap/extension-italic": "^2.1.14", - "@tiptap/extension-link": "^2.1.14", - "@tiptap/extension-list-item": "^2.1.14", - "@tiptap/extension-ordered-list": "^2.1.14", - "@tiptap/extension-paragraph": "^2.1.14", - "@tiptap/extension-strike": "^2.1.14", - "@tiptap/extension-subscript": "^2.1.14", - "@tiptap/extension-superscript": "^2.1.14", - "@tiptap/extension-table": "^2.1.14", - "@tiptap/extension-table-cell": "^2.1.14", - "@tiptap/extension-table-header": "^2.1.14", - "@tiptap/extension-table-row": "^2.1.14", - "@tiptap/extension-task-item": "^2.1.14", - "@tiptap/extension-task-list": "^2.1.14", - "@tiptap/extension-text": "^2.1.14", - "@tiptap/pm": "^2.1.14", - "@tiptap/suggestion": "^2.1.14", - "@tiptap/vue-2": "^2.1.14", + "@tiptap/core": "^2.4.0", + "@tiptap/extension-blockquote": "^2.4.0", + "@tiptap/extension-bold": "^2.4.0", + "@tiptap/extension-bubble-menu": "^2.4.0", + "@tiptap/extension-bullet-list": "^2.4.0", + "@tiptap/extension-code": "^2.4.0", + "@tiptap/extension-code-block": "^2.4.0", + "@tiptap/extension-code-block-lowlight": "^2.4.0", + "@tiptap/extension-document": "^2.4.0", + "@tiptap/extension-dropcursor": "^2.4.0", + "@tiptap/extension-gapcursor": "^2.4.0", + "@tiptap/extension-hard-break": "^2.4.0", + "@tiptap/extension-heading": "^2.4.0", + "@tiptap/extension-highlight": "^2.4.0", + "@tiptap/extension-history": "^2.4.0", + "@tiptap/extension-horizontal-rule": "^2.4.0", + "@tiptap/extension-image": "^2.4.0", + "@tiptap/extension-italic": "^2.4.0", + "@tiptap/extension-link": "^2.4.0", + "@tiptap/extension-list-item": "^2.4.0", + "@tiptap/extension-ordered-list": "^2.4.0", + "@tiptap/extension-paragraph": "^2.4.0", + "@tiptap/extension-strike": "^2.4.0", + "@tiptap/extension-subscript": "^2.4.0", + "@tiptap/extension-superscript": "^2.4.0", + "@tiptap/extension-table": "^2.4.0", + "@tiptap/extension-table-cell": "^2.4.0", + "@tiptap/extension-table-header": "^2.4.0", + "@tiptap/extension-table-row": "^2.4.0", + "@tiptap/extension-task-item": "^2.4.0", + "@tiptap/extension-task-list": "^2.4.0", + "@tiptap/extension-text": "^2.4.0", + "@tiptap/pm": "^2.4.0", + "@tiptap/suggestion": "^2.4.0", + "@tiptap/vue-2": "^2.4.0", "@vue/apollo-components": "^4.0.0-beta.4", "@vue/apollo-option": "^4.0.0-beta.4", "apollo-upload-client": "15.0.0", diff --git a/scripts/verify-tff-mapping b/scripts/verify-tff-mapping index 4bdb9a4f690..e053339c02a 100755 --- a/scripts/verify-tff-mapping +++ b/scripts/verify-tff-mapping @@ -364,6 +364,17 @@ tests = [ ee/spec/graphql/types/remote_development/workspace_type_spec.rb ee/spec/requests/api/graphql/remote_development/workspace/with_id_arg_spec.rb ] + }, + { + explanation: 'Run database dictionary related specs on db/docs changes.', + changed_file: 'db/docs/design_management_repositories.yml', + expected: %w[ + ee/spec/lib/gitlab/database/desired_sharding_key_spec.rb + spec/db/docs_spec.rb + spec/lib/gitlab/database/dictionary_spec.rb + spec/lib/gitlab/database/no_new_tables_with_gitlab_main_schema_spec.rb + spec/lib/gitlab/database/sharding_key_spec.rb + ] } ] diff --git a/spec/controllers/concerns/product_analytics_tracking_spec.rb b/spec/controllers/concerns/product_analytics_tracking_spec.rb index 247be5429a1..ad8d93a78c7 100644 --- a/spec/controllers/concerns/product_analytics_tracking_spec.rb +++ b/spec/controllers/concerns/product_analytics_tracking_spec.rb @@ -59,6 +59,14 @@ RSpec.describe ProductAnalyticsTracking, :snowplow, feature_category: :product_a before do allow(Gitlab::InternalEvents::EventDefinitions).to receive(:known_event?).with('an_event').and_return(true) + event_definition = instance_double( + Gitlab::Tracking::EventDefinition, + event_selection_rules: [ + { name: event_name, time_framed?: false, filter: {} }, + { name: event_name, time_framed?: true, filter: {} } + ] + ) + allow(Gitlab::Tracking::EventDefinition).to receive(:find).with(event_name).and_return(event_definition) end context 'when user is logged in' do diff --git a/spec/frontend/content_editor/components/bubble_menus/media_bubble_menu_spec.js b/spec/frontend/content_editor/components/bubble_menus/media_bubble_menu_spec.js index ea18981d00f..0266129b21c 100644 --- a/spec/frontend/content_editor/components/bubble_menus/media_bubble_menu_spec.js +++ b/spec/frontend/content_editor/components/bubble_menus/media_bubble_menu_spec.js @@ -22,21 +22,13 @@ import { PROJECT_WIKI_ATTACHMENT_DRAWIO_DIAGRAM_HTML, } from '../../test_constants'; -const TIPTAP_AUDIO_HTML = `
- gitlab favicon -
`; +const TIPTAP_AUDIO_HTML = ``; -const TIPTAP_DIAGRAM_HTML = `-
`; +const TIPTAP_DIAGRAM_HTML = `-
`; -const TIPTAP_IMAGE_HTML = `
-
`; +const TIPTAP_IMAGE_HTML = `-
`; -const TIPTAP_VIDEO_HTML = `
- gitlab favicon -
`; +const TIPTAP_VIDEO_HTML = ``; const createFakeEvent = () => ({ preventDefault: jest.fn(), stopPropagation: jest.fn() }); @@ -110,7 +102,7 @@ describe.each` tiptapEditor .chain() .insertContent(mediaHTML) - .setNodeSelection(4) // select the media + .setNodeSelection(1) // select the media .run(); contentEditor.resolveUrl.mockResolvedValue(`/group1/project1/-/wikis/${filePath}`); diff --git a/spec/frontend/content_editor/extensions/diagram_spec.js b/spec/frontend/content_editor/extensions/diagram_spec.js index c611e05884f..9509d946f46 100644 --- a/spec/frontend/content_editor/extensions/diagram_spec.js +++ b/spec/frontend/content_editor/extensions/diagram_spec.js @@ -49,7 +49,7 @@ describe('content_editor/extensions/diagram', () => { doc( diagram( { language: 'mermaid' }, - 'pie title NETFLIX\n "Time spent looking for movie" : 90\n "Time spent watching it" : 10', + 'pie title NETFLIX "Time spent looking for movie" : 90 "Time spent watching it" : 10', ), ).toJSON(), ); diff --git a/spec/frontend/design_management/components/design_notes/design_note_spec.js b/spec/frontend/design_management/components/design_notes/design_note_spec.js index 8c9bf8da3fb..638b12a11b2 100644 --- a/spec/frontend/design_management/components/design_notes/design_note_spec.js +++ b/spec/frontend/design_management/components/design_notes/design_note_spec.js @@ -10,6 +10,7 @@ import EmojiPicker from '~/emoji/components/picker.vue'; import DesignNoteAwardsList from '~/design_management/components/design_notes/design_note_awards_list.vue'; import DesignNote from '~/design_management/components/design_notes/design_note.vue'; import DesignReplyForm from '~/design_management/components/design_notes/design_reply_form.vue'; +import ImportedBadge from '~/vue_shared/components/imported_badge.vue'; import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; import designNoteAwardEmojiToggleMutation from '~/design_management/graphql/mutations/design_note_award_emoji_toggle.mutation.graphql'; import { mockAwardEmoji } from '../../mock_data/apollo_mock'; @@ -25,6 +26,7 @@ const note = { }, awardEmoji: mockAwardEmoji, body: 'test', + imported: false, userPermissions: { adminNote: false, awardEmoji: true, @@ -43,6 +45,7 @@ describe('Design note component', () => { const findUserAvatar = () => wrapper.findComponent(GlAvatar); const findUserAvatarLink = () => wrapper.findComponent(GlAvatarLink); + const findImportedBadge = () => wrapper.findComponent(ImportedBadge); const findUserLink = () => wrapper.findByTestId('user-link'); const findDesignNoteAwardsList = () => wrapper.findComponent(DesignNoteAwardsList); const findReplyForm = () => wrapper.findComponent(DesignReplyForm); @@ -136,6 +139,10 @@ describe('Design note component', () => { expect(wrapper.findComponent(TimeAgoTooltip).exists()).toBe(true); }); + it('should not render imported badge', () => { + expect(findImportedBadge().exists()).toBe(false); + }); + it('should render emoji awards list', () => { expect(findDesignNoteAwardsList().exists()).toBe(true); }); @@ -174,6 +181,21 @@ describe('Design note component', () => { }); }); + describe('when note is imported', () => { + it('should render imported badge', () => { + createComponent({ + props: { + note: { + ...note, + imported: true, + }, + }, + }); + + expect(findImportedBadge().props('importableType')).toBe('comment'); + }); + }); + describe('when user has a permission to edit note', () => { it('should open an edit form on edit button click', async () => { createComponent({ diff --git a/spec/frontend/design_management/mock_data/apollo_mock.js b/spec/frontend/design_management/mock_data/apollo_mock.js index 89267900aea..a51bc11126e 100644 --- a/spec/frontend/design_management/mock_data/apollo_mock.js +++ b/spec/frontend/design_management/mock_data/apollo_mock.js @@ -282,6 +282,7 @@ export const mockNoteSubmitSuccessMutationResponse = { width: 695, __typename: 'DiffPosition', }, + imported: false, userPermissions: { adminNote: true, repositionNote: true, diff --git a/spec/frontend/design_management/mock_data/discussion.js b/spec/frontend/design_management/mock_data/discussion.js index fbd5a9e0103..691dbb19e1e 100644 --- a/spec/frontend/design_management/mock_data/discussion.js +++ b/spec/frontend/design_management/mock_data/discussion.js @@ -17,6 +17,7 @@ export default { author: mockAuthor, awardEmoji: mockAwardEmoji, createdAt: '2020-05-08T07:10:45Z', + imported: false, userPermissions: { repositionNote: true, awardEmoji: true, @@ -39,6 +40,7 @@ export default { }, awardEmoji: mockAwardEmoji, createdAt: '2020-05-08T07:10:45Z', + imported: false, userPermissions: { adminNote: true, awardEmoji: true, diff --git a/spec/frontend/design_management/mock_data/notes.js b/spec/frontend/design_management/mock_data/notes.js index 0477f254042..206f243c1cd 100644 --- a/spec/frontend/design_management/mock_data/notes.js +++ b/spec/frontend/design_management/mock_data/notes.js @@ -20,6 +20,7 @@ const DISCUSSION_2 = { }, awardEmoji: mockAwardEmoji, createdAt: '2020-05-08T07:10:45Z', + imported: false, userPermissions: { adminNote: true, awardEmoji: true, @@ -49,6 +50,7 @@ export const DISCUSSION_3 = { }, awardEmoji: mockAwardEmoji, createdAt: '2020-05-09T07:10:45Z', + imported: false, userPermissions: { adminNote: true, awardEmoji: true, diff --git a/spec/graphql/types/notes/note_type_spec.rb b/spec/graphql/types/notes/note_type_spec.rb index 8163c5c772c..ef049d71e25 100644 --- a/spec/graphql/types/notes/note_type_spec.rb +++ b/spec/graphql/types/notes/note_type_spec.rb @@ -11,6 +11,7 @@ RSpec.describe GitlabSchema.types['Note'], feature_category: :team_planning do body body_html award_emoji + imported internal created_at discussion diff --git a/spec/lib/api/entities/project_spec.rb b/spec/lib/api/entities/project_spec.rb index 2c2cabba5e9..b2402234a4b 100644 --- a/spec/lib/api/entities/project_spec.rb +++ b/spec/lib/api/entities/project_spec.rb @@ -2,54 +2,151 @@ require 'spec_helper' -RSpec.describe ::API::Entities::Project do - let(:project) { create(:project, :public) } - let(:current_user) { create(:user) } - let(:options) { { current_user: current_user } } +RSpec.describe ::API::Entities::Project, feature_category: :groups_and_projects do + let_it_be(:project) { create(:project, :private) } + let_it_be(:current_user) { create(:user) } - let(:entity) do - described_class.new(project, options) - end + let(:options) { { current_user: current_user, statistics: true } } + let(:entity) { described_class.new(project, options) } subject(:json) { entity.as_json } - context 'without project feature' do - before do - project.project_feature.destroy! - project.reload + before do + allow(Gitlab.config.registry).to receive(:enabled).and_return(true) + end + + context 'as a guest' do + before_all do + project.add_guest(current_user) end - it 'returns a response' do - expect(json[:issues_access_level]).to be_nil - expect(json[:repository_access_level]).to be_nil - expect(json[:merge_requests_access_level]).to be_nil + it 'exposes the correct attributes' do + expect(json.keys).to contain_exactly( + :id, :description, :name, :name_with_namespace, :path, :path_with_namespace, + :created_at, :tag_list, :topics, :ssh_url_to_repo, :http_url_to_repo, :web_url, + :avatar_url, :star_count, :last_activity_at, :namespace, :container_registry_image_prefix, + :_links, :empty_repo, :archived, :visibility, :owner, :open_issues_count, + :description_html, :updated_at, :can_create_merge_request_in, :shared_with_groups + ) end end - describe '.service_desk_address', feature_category: :service_desk do - before do - allow(project).to receive(:service_desk_enabled?).and_return(true) + context 'as a reporter' do + before_all do + project.add_reporter(current_user) end - context 'when a user can admin issues' do + it 'exposes the correct attributes' do + expect(json.keys).to contain_exactly( + :id, :description, :name, :name_with_namespace, :path, :path_with_namespace, + :created_at, :default_branch, :tag_list, :topics, :ssh_url_to_repo, :http_url_to_repo, + :web_url, :readme_url, :forks_count, :avatar_url, :star_count, :last_activity_at, + :namespace, :container_registry_image_prefix, :_links, :empty_repo, :archived, + :visibility, :owner, :open_issues_count, :description_html, :updated_at, + :can_create_merge_request_in, :statistics, :ci_config_path, :shared_with_groups, :service_desk_address + ) + end + end + + context 'as a developer' do + before_all do + project.add_developer(current_user) + end + + it 'exposes the correct attributes' do + expect(json.keys).to contain_exactly( + :id, :description, :name, :name_with_namespace, :path, :path_with_namespace, + :created_at, :default_branch, :tag_list, :topics, :ssh_url_to_repo, :http_url_to_repo, + :web_url, :readme_url, :forks_count, :avatar_url, :star_count, :last_activity_at, + :namespace, :container_registry_image_prefix, :_links, :empty_repo, :archived, + :visibility, :owner, :open_issues_count, :description_html, :updated_at, + :can_create_merge_request_in, :statistics, :ci_config_path, :shared_with_groups, :service_desk_address + ) + end + end + + context 'as a maintainer' do + before_all do + project.add_maintainer(current_user) + end + + it 'exposes the correct attributes' do + expected_fields = [ + :id, :description, :name, :name_with_namespace, :path, :path_with_namespace, + :created_at, :default_branch, :tag_list, :topics, :ssh_url_to_repo, :http_url_to_repo, + :web_url, :readme_url, :forks_count, :avatar_url, :star_count, :last_activity_at, + :namespace, :container_registry_image_prefix, :_links, :empty_repo, :archived, + :visibility, :owner, :open_issues_count, :description_html, :updated_at, + :can_create_merge_request_in, :statistics, :ci_config_path, :shared_with_groups, :service_desk_address, + :emails_disabled, :emails_enabled, :resolve_outdated_diff_discussions, + :container_expiration_policy, :repository_object_format, :shared_runners_enabled, + :lfs_enabled, :creator_id, :import_url, :import_type, :import_status, + :import_error, :ci_default_git_depth, :ci_forward_deployment_enabled, + :ci_forward_deployment_rollback_allowed, :ci_job_token_scope_enabled, + :ci_separated_caches, :ci_allow_fork_pipelines_to_run_in_parent_project, :build_git_strategy, + :keep_latest_artifact, :restrict_user_defined_variables, :runners_token, + :runner_token_expiration_interval, :group_runners_enabled, :auto_cancel_pending_pipelines, + :build_timeout, :auto_devops_enabled, :auto_devops_deploy_strategy, :public_jobs, + :only_allow_merge_if_pipeline_succeeds, :allow_merge_on_skipped_pipeline, + :request_access_enabled, :only_allow_merge_if_all_discussions_are_resolved, + :remove_source_branch_after_merge, :printing_merge_request_link_enabled, + :merge_method, :squash_option, :enforce_auth_checks_on_uploads, + :suggestion_commit_message, :merge_commit_template, :squash_commit_template, + :issue_branch_template, :warn_about_potentially_unwanted_characters, + :autoclose_referenced_issues, :packages_enabled, :service_desk_enabled, :issues_enabled, + :merge_requests_enabled, :wiki_enabled, :jobs_enabled, :snippets_enabled, + :container_registry_enabled, :issues_access_level, :repository_access_level, + :merge_requests_access_level, :forking_access_level, :wiki_access_level, + :builds_access_level, :snippets_access_level, :pages_access_level, :analytics_access_level, + :container_registry_access_level, :security_and_compliance_access_level, + :releases_access_level, :environments_access_level, :feature_flags_access_level, + :infrastructure_access_level, :monitor_access_level, :model_experiments_access_level, + :model_registry_access_level + ] + + if Gitlab.ee? + expected_fields += [ + :requirements_enabled, :security_and_compliance_enabled, + :requirements_access_level, :compliance_frameworks + ] + end + + expect(json.keys).to match(expected_fields) + end + + context 'without project feature' do before do - project.add_reporter(current_user) + project.project_feature.destroy! + project.reload end - it 'is present' do - expect(json[:service_desk_address]).to be_present - end - end - - context 'when a user can not admin project' do - it 'is empty' do - expect(json[:service_desk_address]).to be_nil + it 'returns nil for all features' do + expect(json[:issues_access_level]).to be_nil + expect(json[:repository_access_level]).to be_nil + expect(json[:merge_requests_access_level]).to be_nil + expect(json[:forking_access_level]).to be_nil + expect(json[:wiki_access_level]).to be_nil + expect(json[:builds_access_level]).to be_nil + expect(json[:snippets_access_level]).to be_nil + expect(json[:pages_access_level]).to be_nil + expect(json[:analytics_access_level]).to be_nil + expect(json[:container_registry_access_level]).to be_nil + expect(json[:security_and_compliance_access_level]).to be_nil + expect(json[:releases_access_level]).to be_nil + expect(json[:environments_access_level]).to be_nil + expect(json[:feature_flags_access_level]).to be_nil + expect(json[:infrastructure_access_level]).to be_nil + expect(json[:monitor_access_level]).to be_nil + expect(json[:model_experiments_access_level]).to be_nil + expect(json[:model_registry_access_level]).to be_nil end end end - describe '.shared_with_groups' do - let(:group) { create(:group, :private) } + describe 'shared_with_groups' do + let_it_be(:group) { create(:group, :private) } + + subject(:shared_with_groups) { json[:shared_with_groups].as_json } before do project.project_group_links.create!(group: group) @@ -57,39 +154,17 @@ RSpec.describe ::API::Entities::Project do context 'when the current user does not have access to the group' do it 'is empty' do - expect(json[:shared_with_groups]).to be_empty + expect(shared_with_groups).to be_empty end end context 'when the current user has access to the group' do - before do + before_all do group.add_guest(current_user) end it 'contains information about the shared group' do - expect(json[:shared_with_groups]).to contain_exactly(include(group_id: group.id)) - end - end - end - - describe '.ci/cd settings' do - context 'when the user is not an admin' do - before do - project.add_reporter(current_user) - end - - it 'does not return ci settings' do - expect(json[:ci_default_git_depth]).to be_nil - end - end - - context 'when the user has admin privileges' do - before do - project.add_maintainer(current_user) - end - - it 'returns ci settings' do - expect(json[:ci_default_git_depth]).to be_present + expect(shared_with_groups[0]['group_id']).to eq(group.id) end end end diff --git a/spec/lib/gitlab/internal_events_spec.rb b/spec/lib/gitlab/internal_events_spec.rb index 09377ef65a4..f697b2212d4 100644 --- a/spec/lib/gitlab/internal_events_spec.rb +++ b/spec/lib/gitlab/internal_events_spec.rb @@ -16,6 +16,8 @@ RSpec.describe Gitlab::InternalEvents, :snowplow, feature_category: :product_ana allow(Gitlab::Redis::SharedState).to receive(:with).and_yield(redis) allow(Gitlab::Tracking).to receive(:tracker).and_return(fake_snowplow) allow(Gitlab::InternalEvents::EventDefinitions).to receive(:unique_properties).and_return(unique_properties) + allow(Gitlab::Tracking::EventDefinition).to receive(:find).and_return(event_definition) + allow(event_definition).to receive(:event_selection_rules).and_return(event_selection_rules) allow(fake_snowplow).to receive(:event) end @@ -41,10 +43,8 @@ RSpec.describe Gitlab::InternalEvents, :snowplow, feature_category: :product_ana end def expect_redis_tracking - call_index = 0 - expect(redis).to have_received(:incr).twice do |redis_key| - expect(redis_key).to end_with(redis_arguments[call_index]) - call_index += 1 + redis_arguments.each do |redis_argument| + expect(redis).to have_received(:incr).with(a_string_ending_with(redis_argument)) end end @@ -98,13 +98,22 @@ RSpec.describe Gitlab::InternalEvents, :snowplow, feature_category: :product_ana let_it_be(:additional_properties) { {} } let(:redis) { instance_double('Redis') } + let(:event_definition) { instance_double(Gitlab::Tracking::EventDefinition) } + let(:event_selection_rules) do + [ + { name: event_name, time_framed?: false, filter: {} }, + { name: event_name, time_framed?: true, filter: {} } + ] + end + let(:fake_snowplow) { instance_double(Gitlab::Tracking::Destinations::Snowplow) } let(:event_name) { 'g_edit_by_web_ide' } let(:category) { 'InternalEventTracking' } let(:unique_properties) { [:user] } let(:unique_value) { user.id } let(:property_name) { :user } - let(:redis_arguments) { [event_name, Date.today.strftime('%G-%V')] } + let(:week_suffix) { Date.today.strftime('%G-%V') } + let(:redis_arguments) { [event_name, week_suffix] } context 'when only user is passed' do let(:project) { nil } @@ -174,6 +183,79 @@ RSpec.describe Gitlab::InternalEvents, :snowplow, feature_category: :product_ana expect_snowplow_tracking(nil, additional_properties) end + + context 'when a filter is defined' do + let(:time_framed) { true } + let(:event_selection_rules) do + [ + { name: event_name, time_framed?: time_framed, filter: {} }, + { name: event_name, time_framed?: time_framed, filter: { label: 'label_name' } }, + { name: event_name, time_framed?: time_framed, filter: { label: 'another_label_value' } }, + { name: event_name, time_framed?: time_framed, filter: { label: 'label_name', value: 16.17 } } + ] + end + + context 'when event selection rule is time framed' do + let(:redis_arguments) do + [ + "filter:[label:label_name]-#{week_suffix}", + "filter:[label:label_name,value:16.17]-#{week_suffix}", + "#{event_name}-#{week_suffix}" + ] + end + + it 'updates the correct redis keys' do + described_class.track_event( + event_name, + additional_properties: additional_properties, + user: user, + project: project + ) + + expect_redis_tracking + end + end + + context 'when event selection rule is not time framed' do + let(:time_framed) { false } + let(:redis_arguments) do + [ + "filter:[label:label_name]", + "filter:[label:label_name,value:16.17]", + event_name.to_s + ] + end + + context 'when a matching event is tracked' do + it 'updates the matching redis keys' do + described_class.track_event( + event_name, + additional_properties: additional_properties, + user: user, + project: project + ) + + expect_redis_tracking + end + end + + context 'when a non-matching event is tracked' do + let(:additional_properties) { { label: 'unrelated_string' } } + let(:redis_arguments) { [event_name.to_s] } + + it 'updates only the matching redis keys' do + described_class.track_event( + event_name, + additional_properties: additional_properties, + user: user, + project: project + ) + + expect_redis_tracking + end + end + end + end end context 'when feature_enabled_by_namespace_ids is passed' do @@ -312,16 +394,7 @@ RSpec.describe Gitlab::InternalEvents, :snowplow, feature_category: :product_ana end context 'when unique key is defined' do - let(:event_name) { 'p_ci_templates_terraform_base_latest' } - let(:unique_value) { project.id } - let(:property_names) { [:project] } - let(:property_name) { :project } - - before do - allow(Gitlab::InternalEvents::EventDefinitions).to receive(:unique_properties) - .with(event_name) - .and_return(property_names) - end + let(:event_name) { 'i_code_review_saved_replies_use_in_other' } it 'is used when logging to RedisHLL', :aggregate_failures do described_class.track_event(event_name, user: user, project: project) @@ -332,9 +405,9 @@ RSpec.describe Gitlab::InternalEvents, :snowplow, feature_category: :product_ana end context 'when property is missing' do - let(:unique_value) { project.id } - let(:property_names) { [:project] } - let(:property_name) { :project } + let(:unique_value) { user.id } + let(:property_names) { [:user] } + let(:property_name) { :user } it 'logs error' do expect { described_class.track_event(event_name, merge_request_id: 1) }.not_to raise_error @@ -345,7 +418,7 @@ RSpec.describe Gitlab::InternalEvents, :snowplow, feature_category: :product_ana end context 'when there are multiple unique keys' do - let(:property_names) { [:project, :user] } + let(:unique_properties) { [:project, :user] } it 'all of them are used when logging to RedisHLL', :aggregate_failures do described_class.track_event(event_name, user: user, project: project) @@ -386,6 +459,34 @@ RSpec.describe Gitlab::InternalEvents, :snowplow, feature_category: :product_ana end end + describe '#convert_event_selection_rule_to_path_part' do + context 'without a filter' do + let(:event_selection_rule) { { name: 'example_event' } } + + it 'returns the event name' do + expect(described_class.convert_event_selection_rule_to_path_part(event_selection_rule)).to eq('example_event') + end + end + + context 'with a single property filter' do + let(:event_selection_rule) { { name: 'example_event', filter: { label: 'npm' } } } + + it 'returns the correct path with filter' do + expect(described_class.convert_event_selection_rule_to_path_part(event_selection_rule)) + .to eq('example_event-filter:[label:npm]') + end + end + + context 'with a multi property filter that are unordered' do + let(:event_selection_rule) { { name: 'example_event', filter: { property: 'deploy_token', label: 'npm' } } } + + it 'returns the correct path with filter' do + expect(described_class.convert_event_selection_rule_to_path_part(event_selection_rule)) + .to eq('example_event-filter:[label:npm,property:deploy_token]') + end + end + end + describe 'Product Analytics tracking' do let(:app_id) { 'foobar' } let(:url) { 'http://localhost:4000' } diff --git a/spec/lib/gitlab/tracking/event_definition_spec.rb b/spec/lib/gitlab/tracking/event_definition_spec.rb index 30874e87dbf..ba2427a75fb 100644 --- a/spec/lib/gitlab/tracking/event_definition_spec.rb +++ b/spec/lib/gitlab/tracking/event_definition_spec.rb @@ -149,4 +149,28 @@ RSpec.describe Gitlab::Tracking::EventDefinition, feature_category: :service_pin end end end + + describe '.find' do + let(:event_definition1) { described_class.new(nil, { action: 'event1' }) } + let(:event_definition2) { described_class.new(nil, { action: 'event2' }) } + + before do + described_class.clear_memoization(:find) + allow(described_class).to receive(:definitions).and_return([event_definition1, event_definition2]) + end + + it 'finds the event definition by action' do + expect(described_class.find('event1')).to eq(event_definition1) + end + + it 'memorizes results' do + expect(described_class).to receive(:definitions).exactly(3).times.and_call_original + + 10.times do + described_class.find('event1') + described_class.find('event2') + described_class.find('non-existing-event') + end + end + end end diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/total_count_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/total_count_metric_spec.rb index b357d6ea7e4..69390a562da 100644 --- a/spec/lib/gitlab/usage/metrics/instrumentations/total_count_metric_spec.rb +++ b/spec/lib/gitlab/usage/metrics/instrumentations/total_count_metric_spec.rb @@ -6,6 +6,24 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::TotalCountMetric, :clea feature_category: :product_analytics_data_management do before do allow(Gitlab::InternalEvents::EventDefinitions).to receive(:known_event?).and_return(true) + + event_definition = instance_double( + Gitlab::Tracking::EventDefinition, + event_selection_rules: [{ name: 'my_event', time_framed?: false, filter: {} }] + ) + allow(Gitlab::Tracking::EventDefinition).to receive(:find).with('my_event').and_return(event_definition) + + event_definition1 = instance_double( + Gitlab::Tracking::EventDefinition, + event_selection_rules: [{ name: 'my_event1', time_framed?: false, filter: {} }] + ) + allow(Gitlab::Tracking::EventDefinition).to receive(:find).with('my_event1').and_return(event_definition1) + + event_definition2 = instance_double( + Gitlab::Tracking::EventDefinition, + event_selection_rules: [{ name: 'my_event2', time_framed?: false, filter: {} }] + ) + allow(Gitlab::Tracking::EventDefinition).to receive(:find).with('my_event2').and_return(event_definition2) end context 'with multiple similar events' do diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index 01de572c829..b0ffba5cf8c 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -479,6 +479,32 @@ RSpec.describe Ci::Build, feature_category: :continuous_integration, factory_def end end + describe 'scopes for preloading' do + let_it_be(:runner) { create(:ci_runner) } + let_it_be(:user) { create(:user).tap { |user| create(:user_detail, user: user) } } + + before_all do + build = create(:ci_build, :trace_artifact, :artifacts, :test_reports, pipeline: pipeline) + build.runner = runner + build.user = user + build.save! + end + + describe '.eager_load_for_api' do + subject(:eager_load_for_api) { described_class.eager_load_for_api } + + it { expect(eager_load_for_api.last.association(:user)).to be_loaded } + it { expect(eager_load_for_api.last.user.association(:user_detail)).to be_loaded } + it { expect(eager_load_for_api.last.association(:metadata)).to be_loaded } + it { expect(eager_load_for_api.last.association(:job_artifacts_archive)).to be_loaded } + it { expect(eager_load_for_api.last.association(:job_artifacts)).to be_loaded } + it { expect(eager_load_for_api.last.association(:runner)).to be_loaded } + it { expect(eager_load_for_api.last.association(:tags)).to be_loaded } + it { expect(eager_load_for_api.last.association(:pipeline)).to be_loaded } + it { expect(eager_load_for_api.last.pipeline.association(:project)).to be_loaded } + end + end + describe '#stick_build_if_status_changed' do it 'sticks the build if the status changed' do job = create(:ci_build, :pending, pipeline: pipeline) diff --git a/spec/models/integrations/beyond_identity_spec.rb b/spec/models/integrations/beyond_identity_spec.rb index b7618943aa5..3d522fc7f8b 100644 --- a/spec/models/integrations/beyond_identity_spec.rb +++ b/spec/models/integrations/beyond_identity_spec.rb @@ -36,9 +36,9 @@ RSpec.describe Integrations::BeyondIdentity, feature_category: :integrations do end end - describe '.api_fields' do - it 'returns api fields' do - expect(described_class.api_fields).to eq([{ + describe '.api_arguments' do + it 'returns api arguments' do + expect(described_class.api_arguments).to eq([{ required: true, name: :token, type: String, diff --git a/spec/requests/api/ci/jobs_spec.rb b/spec/requests/api/ci/jobs_spec.rb index 31f7d8f3602..f6b482b943b 100644 --- a/spec/requests/api/ci/jobs_spec.rb +++ b/spec/requests/api/ci/jobs_spec.rb @@ -426,16 +426,16 @@ RSpec.describe API::Ci::Jobs, feature_category: :continuous_integration do expect(json_job['pipeline']['status']).to eq job.pipeline.status end - it 'avoids N+1 queries', :skip_before_request do + it 'avoids N+1 queries', :skip_before_request, :use_sql_query_cache do first_build = create(:ci_build, :trace_artifact, :artifacts, :test_reports, pipeline: pipeline) first_build.runner = create(:ci_runner) first_build.user = create(:user) first_build.save! - control = ActiveRecord::QueryRecorder.new { go } + control = ActiveRecord::QueryRecorder.new(skip_cached: false) { go } 5.times do - second_pipeline = create(:ci_empty_pipeline, project: project, sha: project.commit.id, ref: project.default_branch) + second_pipeline = create(:ci_pipeline, project: project, sha: project.commit.id, ref: project.default_branch) second_build = create(:ci_build, :trace_artifact, :artifacts, :test_reports, pipeline: second_pipeline) second_build.runner = create(:ci_runner) second_build.user = create(:user) diff --git a/spec/requests/api/graphql/mutations/ml/models/delete_spec.rb b/spec/requests/api/graphql/mutations/ml/models/delete_spec.rb new file mode 100644 index 00000000000..b502bff52ef --- /dev/null +++ b/spec/requests/api/graphql/mutations/ml/models/delete_spec.rb @@ -0,0 +1,110 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Deleting a model', feature_category: :mlops do + using RSpec::Parameterized::TableSyntax + + include GraphqlHelpers + + let_it_be_with_reload(:model) { create(:ml_models) } + let_it_be(:user) { create(:user) } + + let(:project) { model.project } + let(:id) { model.to_global_id.to_s } + + let(:query) do + <<~GQL + model { + id + } + errors + GQL + end + + let(:params) { { project_path: project.full_path, id: id } } + let(:mutation) { graphql_mutation(:ml_model_delete, params, query) } + let(:mutation_response) { graphql_mutation_response(:ml_model_delete) } + + shared_examples 'destroying the model' do + it 'destroys model' do + expect(::Ml::DestroyModelService).to receive(:new).with(model, user).and_call_original + + expect { mutation_request }.to change { ::Ml::Model.count }.by(-1) + expect(mutation_response['model']).to eq({ "id" => id }) + end + + it_behaves_like 'returning response status', :success + end + + shared_examples 'denying the mutation request' do + it 'does not delete the model' do + expect(::Ml::DestroyModelService).not_to receive(:new) + + expect { mutation_request }.to not_change { ::Ml::Model.count } + + expect(mutation_response).to be_nil + expect_graphql_errors_to_include("The resource that you are attempting to access does not exist or you don't " \ + "have permission to perform this action") + end + + it_behaves_like 'returning response status', :success + end + + shared_examples 'model was not found' do + it 'does not delete the model' do + expect(::Ml::DestroyModelService).not_to receive(:new) + + expect { mutation_request }.to not_change { ::Ml::Model.count } + + expect(mutation_response["errors"]).to match_array(['Model not found']) + end + + it_behaves_like 'returning response status', :success + end + + describe 'post graphql mutation' do + subject(:mutation_request) { post_graphql_mutation(mutation, current_user: user) } + + context 'with valid id' do + where(:user_role, :mutation_behavior) do + :reporter | 'destroying the model' + :guest | 'denying the mutation request' + end + + with_them do + before do + project.public_send("add_#{user_role}", user) + end + + it_behaves_like params[:mutation_behavior] + end + end + + context 'with authorized user' do + before do + project.add_maintainer(user) + end + + context 'with invalid id' do + let(:params) { { project_path: project.full_path, id: "gid://gitlab/Ml::Model/#{non_existing_record_id}" } } + + it_behaves_like 'model was not found' + end + + context 'when an error occurs' do + it 'returns the errors in the response' do + allow_next_found_instance_of(::Ml::Model) do |model| + allow(model).to receive(:destroy).and_return(nil) + errors = ActiveModel::Errors.new(model).tap { |e| e.add(:id, 'some error') } + allow(model).to receive(:errors).and_return(errors) + end + + mutation_request + + expect(mutation_response['errors']).to match_array(['Id some error']) + end + end + end + end +end diff --git a/spec/requests/api/graphql/mutations/ml/models/destroy_spec.rb b/spec/requests/api/graphql/mutations/ml/models/destroy_spec.rb index bd849f30c4e..7cf4cbf14dc 100644 --- a/spec/requests/api/graphql/mutations/ml/models/destroy_spec.rb +++ b/spec/requests/api/graphql/mutations/ml/models/destroy_spec.rb @@ -106,11 +106,13 @@ RSpec.describe 'Destroying a model', feature_category: :mlops do it 'returns the errors in the response' do allow_next_found_instance_of(::Ml::Model) do |model| allow(model).to receive(:destroy).and_return(nil) + errors = ActiveModel::Errors.new(model).tap { |e| e.add(:id, 'some error') } + allow(model).to receive(:errors).and_return(errors) end mutation_request - expect(mutation_response['errors']).to match_array(['Failed to delete model']) + expect(mutation_response['errors']).to match_array(['Id some error']) end end end diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index ed8eda967c4..3a21c7f9ad4 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -1735,14 +1735,6 @@ RSpec.describe API::Projects, :aggregate_failures, feature_category: :groups_and expect(json_response.map { |project| project['id'] }).to contain_exactly(public_project.id) end - it 'includes container_registry_access_level' do - get api("/users/#{user4.id}/projects/", user) - - expect(response).to have_gitlab_http_status(:ok) - expect(json_response).to be_an Array - expect(json_response.first.keys).to include('container_registry_access_level') - end - context 'filter by updated_at' do it 'returns only projects updated on the given timeframe' do get api("/users/#{user.id}/projects", user), diff --git a/spec/services/ml/destroy_model_service_spec.rb b/spec/services/ml/destroy_model_service_spec.rb index fcbafc0a571..0e21d9dc39c 100644 --- a/spec/services/ml/destroy_model_service_spec.rb +++ b/spec/services/ml/destroy_model_service_spec.rb @@ -36,14 +36,14 @@ RSpec.describe ::Ml::DestroyModelService, feature_category: :mlops do before do allow_next_instance_of(Packages::MarkPackagesForDestructionService) do |instance| - allow(instance).to receive(:execute).and_return ServiceResponse.error(message: "") + allow(instance).to receive(:execute).and_return ServiceResponse.error(message: "An error") end end it 'returns success with warning', :aggregate_failures do - expect { service_result }.to change { Ml::Model.count }.by(-1).and change { Ml::ModelVersion.count }.by(-1) - expect(service_result).to be_success - expect(service_result.message).to eq('Model deleted but failed to remove associated packages') + expect { service_result }.not_to change { Ml::Model.count } + expect(service_result).to be_error + expect(service_result.message).to eq("An error") end end end diff --git a/tests.yml b/tests.yml index 355bddb0423..9b5197d8766 100644 --- a/tests.yml +++ b/tests.yml @@ -146,6 +146,17 @@ mapping: - 'spec/db/docs_spec.rb' - 'ee/spec/lib/ee/gitlab/database/docs/docs_spec.rb' + # Run database dictionary related specs on db/docs changes. + # https://gitlab.com/gitlab-org/quality/engineering-productivity/master-broken-incidents/-/issues/6276 + - source: 'db/docs/.+\.yml' + test: + # Found via `git grep Database::Dictionary -l spec ee/spec` + - 'ee/spec/lib/gitlab/database/desired_sharding_key_spec.rb' + - 'spec/db/docs_spec.rb' + - 'spec/lib/gitlab/database/dictionary_spec.rb' + - 'spec/lib/gitlab/database/no_new_tables_with_gitlab_main_schema_spec.rb' + - 'spec/lib/gitlab/database/sharding_key_spec.rb' + # See https://gitlab.com/gitlab-org/quality/engineering-productivity/master-broken-incidents/-/issues/1360 - source: 'vendor/project_templates/.*' test: 'spec/lib/gitlab/project_template_spec.rb' diff --git a/yarn.lock b/yarn.lock index 8dcb94aa478..62ac7397e21 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1826,11 +1826,6 @@ resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.3.tgz#0300943770e04231041a51bd39f0439b5c7ab4f0" integrity sha512-nkalE/f1RvRGChwBnEIoBfSEYOXnCRdleKuv6+lePbMDrMZXeDQnqak5XDOeBgrPPyPfAdcCu/B5z+v3VhplGg== -"@linaria/core@3.0.0-beta.13": - version "3.0.0-beta.13" - resolved "https://registry.yarnpkg.com/@linaria/core/-/core-3.0.0-beta.13.tgz#049c5be5faa67e341e413a0f6b641d5d78d91056" - integrity sha512-3zEi5plBCOsEzUneRVuQb+2SAx3qaC1dj0FfFAI6zIJQoDWu0dlSwKijMRack7oO9tUWrchfj3OkKQAd1LBdVg== - "@mattiasbuelens/web-streams-adapter@^0.1.0": version "0.1.0" resolved "https://registry.yarnpkg.com/@mattiasbuelens/web-streams-adapter/-/web-streams-adapter-0.1.0.tgz#607b5a25682f4ae2741da7ba6df39302505336b3" @@ -1915,40 +1910,10 @@ resolved "https://registry.yarnpkg.com/@rails/ujs/-/ujs-7.0.8-1.tgz#4156942025aa6b016d3d9a7df3e542ac962359e2" integrity sha512-uZRCeEl6zY/9JvjTpQilbJyBqFr4onNJTkQTJgfsXDZPJyqCAvyGGraO0LaiHvWKNqD1fTRamdSYg/l+U7daVA== -"@remirror/core-constants@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@remirror/core-constants/-/core-constants-2.0.0.tgz#a52f89059d93955e00810023cc76b4f7db9650bf" - integrity sha512-vpePPMecHJllBqCWXl6+FIcZqS+tRUM2kSCCKFeEo1H3XUEv3ocijBIPhnlSAa7g6maX+12ATTgxrOsLpWVr2g== - dependencies: - "@babel/runtime" "^7.13.10" - -"@remirror/core-helpers@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@remirror/core-helpers/-/core-helpers-2.0.1.tgz#6847666a009ada8c9b9f3a093c13a6d07a95d9bb" - integrity sha512-s8M1pn33aBUhduvD1QR02uUQMegnFkGaTr4c1iBzxTTyg0rbQstzuQ7Q8TkL6n64JtgCdJS9jLz2dONb2meBKQ== - dependencies: - "@babel/runtime" "^7.13.10" - "@linaria/core" "3.0.0-beta.13" - "@remirror/core-constants" "^2.0.0" - "@remirror/types" "^1.0.0" - "@types/object.omit" "^3.0.0" - "@types/object.pick" "^1.3.1" - "@types/throttle-debounce" "^2.1.0" - case-anything "^2.1.10" - dash-get "^1.0.2" - deepmerge "^4.2.2" - fast-deep-equal "^3.1.3" - make-error "^1.3.6" - object.omit "^3.0.0" - object.pick "^1.3.0" - throttle-debounce "^3.0.1" - -"@remirror/types@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@remirror/types/-/types-1.0.0.tgz#cc8764440089a2ada71f149c409739575b73b12e" - integrity sha512-7HQbW7k8VxrAtfzs9FxwO6XSDabn8tSFDi1wwzShOnU+cvaYpfxu0ygyTk3TpXsag1hgFKY3ZIlAfB4WVz2LkQ== - dependencies: - type-fest "^2.0.0" +"@remirror/core-constants@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@remirror/core-constants/-/core-constants-2.0.2.tgz#f05eccdc69e3a65e7d524b52548f567904a11a1a" + integrity sha512-dyHY+sMF0ihPus3O27ODd4+agdHMEmuRdyiZJ2CCWjPV5UFmn17ZbElvk6WOGVE4rdCJKZQCrPV2BcikOMLUGQ== "@rollup/plugin-graphql@^2.0.4": version "2.0.4" @@ -2673,213 +2638,213 @@ dom-accessibility-api "^0.5.1" pretty-format "^26.4.2" -"@tiptap/core@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-2.1.14.tgz#c30d2227891554c0ad1038d84b0f0c44deebf77b" - integrity sha512-X8FWXWhxrOklNEdhDkSa4PekF3BwGjDfhq7Es95OrdJ3vZ1a5lkbCdx4jXErsX1C4TaIs7cI3tqdflTXhqjLmg== +"@tiptap/core@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-2.4.0.tgz#6f8eee8beb5b89363582366b201ccc4798ac98a9" + integrity sha512-YJSahk8pkxpCs8SflCZfTnJpE7IPyUWIylfgXM2DefjRQa5DZ+c6sNY0s/zbxKYFQ6AuHVX40r9pCfcqHChGxQ== -"@tiptap/extension-blockquote@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/extension-blockquote/-/extension-blockquote-2.1.14.tgz#3c5decf6316ea1d299330f33e77d36047aa8ec54" - integrity sha512-hslTfGzlC52lq3EGaxl1V8tGFsnjGLIlYr5SGJzPYwQcr2WHU/WJZli66HB+8N2o+ox5Cp4gQRNDUd9XsfxChg== +"@tiptap/extension-blockquote@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/extension-blockquote/-/extension-blockquote-2.4.0.tgz#0179076ea2fa12e41a198dad087b81d368653b8d" + integrity sha512-nJJy4KsPgQqWTTDOWzFRdjCfG5+QExfZj44dulgDFNh+E66xhamnbM70PklllXJgEcge7xmT5oKM0gKls5XgFw== -"@tiptap/extension-bold@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/extension-bold/-/extension-bold-2.1.14.tgz#9a0d0274bd0569d5ed37720554264f2a7d3d8bac" - integrity sha512-LeIRHjc6LsZ4JVuvbrb2U18IHvaYwP4+O6lIG2riTmvuqhc1UL2dKeG8X13xfk7OttA89Vkkb/XdjzQvcT1I0Q== +"@tiptap/extension-bold@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/extension-bold/-/extension-bold-2.4.0.tgz#b5ced2c3bf51f304890137dbdf394d58c01eb208" + integrity sha512-csnW6hMDEHoRfxcPRLSqeJn+j35Lgtt1YRiOwn7DlS66sAECGRuoGfCvQSPij0TCDp4VCR9if5Sf8EymhnQumQ== -"@tiptap/extension-bubble-menu@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.1.14.tgz#6a23066934969fc89d2cd8b3b3932e1364712ee9" - integrity sha512-9+KsP2rCVymlSKXx7BhPF9xy7dj2/G7auu7qZ4AJzEbsLj1PMS8/pSjPUabCIN6z+9IeifOa2VKmXCnVfcpazw== +"@tiptap/extension-bubble-menu@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.4.0.tgz#a079329318fc21407f9a3c9c3da6ef72cb0b4ab6" + integrity sha512-s99HmttUtpW3rScWq8rqk4+CGCwergNZbHLTkF6Rp6TSboMwfp+rwL5Q/JkcAG9KGLso1vGyXKbt1xHOvm8zMw== dependencies: tippy.js "^6.3.7" -"@tiptap/extension-bullet-list@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/extension-bullet-list/-/extension-bullet-list-2.1.14.tgz#0e7f07c0f8f51de8378fdea49e7c9626ebb1ffcd" - integrity sha512-dbnYDGNkbtFaCQIqNsOD9cc2JewN4Ref3Qq0NrVoh+MbbX2oJN2vA8rrKmEv1GhxDjtvaj2RiH1ki5XW3P98UQ== +"@tiptap/extension-bullet-list@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/extension-bullet-list/-/extension-bullet-list-2.4.0.tgz#60eea05b5ac8c8e8d615c057559fddb95033abeb" + integrity sha512-9S5DLIvFRBoExvmZ+/ErpTvs4Wf1yOEs8WXlKYUCcZssK7brTFj99XDwpHFA29HKDwma5q9UHhr2OB2o0JYAdw== -"@tiptap/extension-code-block-lowlight@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block-lowlight/-/extension-code-block-lowlight-2.1.14.tgz#f7b9bd0b6a2d6bbbfd2a10d2192831584e132d41" - integrity sha512-FSO8LRt2Ja8d/WQ340z1gW4AUKBECJHxw08ADV0mJpjY+6NnfOID1lqL02Gy15CjO/amccE1DqPHGlcC39WU+Q== +"@tiptap/extension-code-block-lowlight@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block-lowlight/-/extension-code-block-lowlight-2.4.0.tgz#76cd2ffcb1dcd7ba4b2de4db4c561bd43420af3c" + integrity sha512-j0SdFq66A97Cn7bQOMqFYBaYsmOltZZ6o4uDZH6fdTvEFbfXTdtTYs2awsNSbW+w/DtivKZCvAX1FRLR3/g/5A== -"@tiptap/extension-code-block@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block/-/extension-code-block-2.1.14.tgz#5220bd76d0e957e59898ef145142394dbfd58124" - integrity sha512-D+F+bGrmbXzIkZuKUaM5fhJHVoUmDyTdWCqOMOzG5t53GgMDdLQF7LTzOGC2iAVu0CtAxhUEsoIlzPBdV2FKrA== +"@tiptap/extension-code-block@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block/-/extension-code-block-2.4.0.tgz#b7f1da4825677a2ea6b8e970a1197877551e5dc8" + integrity sha512-QWGdv1D56TBGbbJSj2cIiXGJEKguPiAl9ONzJ/Ql1ZksiQsYwx0YHriXX6TOC//T4VIf6NSClHEtwtxWBQ/Csg== -"@tiptap/extension-code@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/extension-code/-/extension-code-2.1.14.tgz#1e62e5e138981b26675a1e2a7d6f446b99727a82" - integrity sha512-7fuDW0+nyzxTlGEdkkrGMkz5b90xAvZq7EPnta13Px7FsSy771dpbWer7xMbpWGh7VYxOG6qpWJouLLrx2FKyQ== +"@tiptap/extension-code@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/extension-code/-/extension-code-2.4.0.tgz#3a9fed3585bf49f445505c2e9ad71fd66e117304" + integrity sha512-wjhBukuiyJMq4cTcK3RBTzUPV24k5n1eEPlpmzku6ThwwkMdwynnMGMAmSF3fErh3AOyOUPoTTjgMYN2d10SJA== -"@tiptap/extension-document@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/extension-document/-/extension-document-2.1.14.tgz#9b5234a7881f8ef222924a67ef771a2bfff8a75e" - integrity sha512-plOcTQBCysUyz8AXrkBhhAqa+ALyeGJPOku0L3lS6MCSAPM2/KRW/H4KXcrfW0G1lHKiJ4OkP8oHksxa6Id5zg== +"@tiptap/extension-document@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/extension-document/-/extension-document-2.4.0.tgz#a396b2cbcc8708aa2a0a41d0be481fda4b61c77b" + integrity sha512-3jRodQJZDGbXlRPERaloS+IERg/VwzpC1IO6YSJR9jVIsBO6xC29P3cKTQlg1XO7p6ZH/0ksK73VC5BzzTwoHg== -"@tiptap/extension-dropcursor@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/extension-dropcursor/-/extension-dropcursor-2.1.14.tgz#a6f2df2a36a5457a3afff3c933b5328147be8f80" - integrity sha512-ZupJ/3ukcuFK/HhWbD7vuEKt10RC1/Jbk8O+HHcAWftAghsXNAnCsKWhJhAs/MvvoBFQEkmVOdPXvQsDXbbCMw== +"@tiptap/extension-dropcursor@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/extension-dropcursor/-/extension-dropcursor-2.4.0.tgz#8f54908f84a4ab7d2d7de7fc0197511138445740" + integrity sha512-c46HoG2PEEpSZv5rmS5UX/lJ6/kP1iVO0Ax+6JrNfLEIiDULUoi20NqdjolEa38La2VhWvs+o20OviiTOKEE9g== -"@tiptap/extension-floating-menu@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/extension-floating-menu/-/extension-floating-menu-2.1.14.tgz#13f9e6cf62bfc3bec5e05e2bac0f6a1f66a909bf" - integrity sha512-o/yNaZ+ntMBCjFL95JyX6LoVb8fsrx0IsnlNtnGUVr8mpOg2JyeN2ZJpUhPo2aR7QuyfdR1XsGG4TRHJBp3fGg== +"@tiptap/extension-floating-menu@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/extension-floating-menu/-/extension-floating-menu-2.4.0.tgz#75c48b98d0f833251eab70f269ed186f48fc398e" + integrity sha512-vLb9v+htbHhXyty0oaXjT3VC8St4xuGSHWUB9GuAJAQ+NajIO6rBPbLUmm9qM0Eh2zico5mpSD1Qtn5FM6xYzg== dependencies: tippy.js "^6.3.7" -"@tiptap/extension-gapcursor@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/extension-gapcursor/-/extension-gapcursor-2.1.14.tgz#fe36282b66f3652c5f7c2d5031b651b2db2a8898" - integrity sha512-wTT8k3msIUBIj3k28ZB8IUdI4zjnkiYGTqzNXud01hLsPuQWkPerW/LqqiyKfsGKSIJa/l8x4ZzUgJv3ciO9YQ== +"@tiptap/extension-gapcursor@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/extension-gapcursor/-/extension-gapcursor-2.4.0.tgz#2a738509d40f5f856492c11e32b10e4462f71216" + integrity sha512-F4y/0J2lseohkFUw9P2OpKhrJ6dHz69ZScABUvcHxjznJLd6+0Zt7014Lw5PA8/m2d/w0fX8LZQ88pZr4quZPQ== -"@tiptap/extension-hard-break@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/extension-hard-break/-/extension-hard-break-2.1.14.tgz#47eea3742a879bf7849377ffdb3549fddffa4474" - integrity sha512-Nv6JS1dmPiiWDJAcdb6nGns7vD65Gqbqxh/RQeT172G2yXu5TD8EJa0OiEhd1sMcEg7OXbHMLtkDzx57mEuZ7Q== +"@tiptap/extension-hard-break@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/extension-hard-break/-/extension-hard-break-2.4.0.tgz#b5bf5b065827280e450fba8f53d137654509d836" + integrity sha512-3+Z6zxevtHza5IsDBZ4lZqvNR3Kvdqwxq/QKCKu9UhJN1DUjsg/l1Jn2NilSQ3NYkBYh2yJjT8CMo9pQIu776g== -"@tiptap/extension-heading@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/extension-heading/-/extension-heading-2.1.14.tgz#868dd4eff41480d31c0cbab04d6d14a682318259" - integrity sha512-x/AMzMANLvgbuwx4qe848WxF5W1Yq4bUjsduSu/5jonpH2sR5AFsH5VbWS8lfT34OdOI0Gs7p+k2NNuykWDPQA== +"@tiptap/extension-heading@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/extension-heading/-/extension-heading-2.4.0.tgz#16302ce691714244c3d3fa92d2db86a5c895a025" + integrity sha512-fYkyP/VMo7YHO76YVrUjd95Qeo0cubWn/Spavmwm1gLTHH/q7xMtbod2Z/F0wd6QHnc7+HGhO7XAjjKWDjldaw== -"@tiptap/extension-highlight@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/extension-highlight/-/extension-highlight-2.1.14.tgz#ce427a031561e8e89436db0dec969cc9ea1c02af" - integrity sha512-TU12/Hw5FBZuk1/j06UqNVx91Hms0XEEgtz3tOwyWrxbOe4hXILNedzrz3aNoTcLJoqOVefw+VBQLcsK0Ztw/Q== +"@tiptap/extension-highlight@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/extension-highlight/-/extension-highlight-2.4.0.tgz#29a200993b0e599223efac373785089109579fd3" + integrity sha512-p2I/CaMrs6hzpj/dSw6UNobOWTV38yTjPK+B4ShJQ7IN2u/C82KOTOeFfJoFd9KykmpVOVW3w3nKG3ad0HXPuQ== -"@tiptap/extension-history@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/extension-history/-/extension-history-2.1.14.tgz#06863c38511d39d309003f8cc187d38fa800dbe5" - integrity sha512-DN9QeiEv/Y3cCOHVH+/0M18btg7Gebhw7ooT0afanyHS/a5aV/IsgDnw6YRHaMfLUgDD7toOSSbjgGYWZX307w== +"@tiptap/extension-history@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/extension-history/-/extension-history-2.4.0.tgz#1dbf8410c091175627414d48a0d857232a8f4094" + integrity sha512-gr5qsKAXEVGr1Lyk1598F7drTaEtAxqZiuuSwTCzZzkiwgEQsWMWTWc9F8FlneCEaqe1aIYg6WKWlmYPaFwr0w== -"@tiptap/extension-horizontal-rule@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.1.14.tgz#23c4ffad88b8554e280344d70592bcd6702215fd" - integrity sha512-n5vNE4rTA3zfLhe0p3k38IJGtEWfvr2QIp5lQuw4/i5TcOrnpfryJwA9tLDTgAdcyvTTGJH5jAXWw9ENxBexQg== +"@tiptap/extension-horizontal-rule@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.4.0.tgz#7f27c0778004602686251af7e2f7a8461a3d77ba" + integrity sha512-yDgxy+YxagcEsBbdWvbQiXYxsv3noS1VTuGwc9G7ZK9xPmBHJ5y0agOkB7HskwsZvJHoaSqNRsh7oZTkf0VR3g== -"@tiptap/extension-image@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/extension-image/-/extension-image-2.1.14.tgz#5e5b662afd35d6a41ce9fb1fee72da8e3318e2d9" - integrity sha512-EDwbvBIpyJJDAtIlNNBDPtIIAi0GKEAOcqyB7G0tomyho6QUaO2yFtB37t7OAbM+CQiTBtO2AuJhOYr3354V4A== +"@tiptap/extension-image@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/extension-image/-/extension-image-2.4.0.tgz#21a18e80ed6bc330cf8ab2ca990a3addb40916c8" + integrity sha512-NIVhRPMO/ONo8OywEd+8zh0Q6Q7EbFHtBxVsvfOKj9KtZkaXQfUO4MzONTyptkvAchTpj9pIzeaEY5fyU87gFA== -"@tiptap/extension-italic@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/extension-italic/-/extension-italic-2.1.14.tgz#2542ee68202307ed01bd5e10b65650e99b6efa4f" - integrity sha512-K+n2ts26HNatX3FZ2pYJTFDuMypDyMP4jQ3T11cU908lUT8gHXHBcgh0OW83SX92asbWxUj8xEdDZczi7Qqbew== +"@tiptap/extension-italic@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/extension-italic/-/extension-italic-2.4.0.tgz#42ab003e04e1e8d825f698914c0e80ac849144f1" + integrity sha512-aaW/L9q+KNHHK+X73MPloHeIsT191n3VLd3xm6uUcFDnUNvzYJ/q65/1ZicdtCaOLvTutxdrEvhbkrVREX6a8g== -"@tiptap/extension-link@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/extension-link/-/extension-link-2.1.14.tgz#aa850dddfaec14afe99bd3ba6695d515eecadc92" - integrity sha512-lfZIBaGGWJaX9tZIsAq5WuWk1cIQVM3takU4F5485eN8aM7Nnw/+Se8uSPZeh3rCbiNg5EeGi/eLEZv/L/TLGQ== +"@tiptap/extension-link@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/extension-link/-/extension-link-2.4.0.tgz#e44edfe2f8d878959bd3ad64fda1b9e232f1f011" + integrity sha512-r3PjT0bjSKAorHAEBPA0icSMOlqALbxVlWU9vAc+Q3ndzt7ht0CTPNewzFF9kjzARABVt1cblXP/2+c0qGzcsg== dependencies: linkifyjs "^4.1.0" -"@tiptap/extension-list-item@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/extension-list-item/-/extension-list-item-2.1.14.tgz#f17c3b9cff2a710c3307c0298261c81f2a5d7cdd" - integrity sha512-MpOCf0QnbW0qxW4dB7JRMX7qGortjY8QRl1WBmUGBBN54Q712nfgmUmNJmzNYfRU91PN0afdBVibUSchB4LP3Q== +"@tiptap/extension-list-item@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/extension-list-item/-/extension-list-item-2.4.0.tgz#a97a48850b81e94b9a60cc2aa16e515aa5311456" + integrity sha512-reUVUx+2cI2NIAqMZhlJ9uK/+zvRzm1GTmlU2Wvzwc7AwLN4yemj6mBDsmBLEXAKPvitfLh6EkeHaruOGymQtg== -"@tiptap/extension-ordered-list@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/extension-ordered-list/-/extension-ordered-list-2.1.14.tgz#61d198f146d9c71b3809398263b4093616b2e545" - integrity sha512-XwARMGQbTbBOOvG62T4yH2g8OeoLYVaNTKRbiuhIzYekAN/elnydQahcjjE9/Y2Zq54g0nPdgh0LvsjWNWxr8Q== +"@tiptap/extension-ordered-list@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/extension-ordered-list/-/extension-ordered-list-2.4.0.tgz#6cf82e10d7e7f7cc44156d29b0b71a22dec31612" + integrity sha512-Zo0c9M0aowv+2+jExZiAvhCB83GZMjZsxywmuOrdUbq5EGYKb7q8hDyN3hkrktVHr9UPXdPAYTmLAHztTOHYRA== -"@tiptap/extension-paragraph@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/extension-paragraph/-/extension-paragraph-2.1.14.tgz#ec993235ac4ceca5026c0e821d2d72e9d5e3c4f9" - integrity sha512-iWD1nfMvADrx2pwxlQXu2PDnNghhU2EvAOmNOzGOEzkTaELkPR4CDyr/wEi1ewS9dNhhO8EpP8IYVXzd01r8JA== +"@tiptap/extension-paragraph@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/extension-paragraph/-/extension-paragraph-2.4.0.tgz#5b9aea8775937b327bbe6754be12ae3144fb09ff" + integrity sha512-+yse0Ow67IRwcACd9K/CzBcxlpr9OFnmf0x9uqpaWt1eHck1sJnti6jrw5DVVkyEBHDh/cnkkV49gvctT/NyCw== -"@tiptap/extension-strike@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/extension-strike/-/extension-strike-2.1.14.tgz#8a94de5ec6bf726ff0ef73f998bad9d863d3a65d" - integrity sha512-AcFiyUc2eiL3TM5flvExIi+LjukaGzSKGGuLH1Q9e7T4GkfZu7FaSzjP1+2kvgwGAMJxgm5Ybzvugcf9rrNosA== +"@tiptap/extension-strike@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/extension-strike/-/extension-strike-2.4.0.tgz#f09c4f51f7fed01c356026d7e8d8a1d1f2ac8f18" + integrity sha512-pE1uN/fQPOMS3i+zxPYMmPmI3keubnR6ivwM+KdXWOMnBiHl9N4cNpJgq1n2eUUGKLurC2qrQHpnVyGAwBS6Vg== -"@tiptap/extension-subscript@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/extension-subscript/-/extension-subscript-2.1.14.tgz#c6796abbb9d1654e8ab12c1b97354aac85754695" - integrity sha512-HYKqCkP4ncbHJFXxqafZUUHdL8raKqaw/DJ8Ogmk8luOqaFjgOGcgFRhtWyXCbv/BJCL42/0IGeoM5D4aRo/gg== +"@tiptap/extension-subscript@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/extension-subscript/-/extension-subscript-2.4.0.tgz#58c1d364ed8bd817f66b4a498f7cca09737c39ee" + integrity sha512-exLSmSFmYN6AVww5oyroFL3KCwstT0U+ojvVhRD6DQ+Hc81d++lBKANfsWAcllXjZVGPWeMNdE66bV7oFCtQcQ== -"@tiptap/extension-superscript@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/extension-superscript/-/extension-superscript-2.1.14.tgz#1ce5646d5c5a2bbf009c563de14cdf879156811a" - integrity sha512-L44OToFzSULAM+8wfbDa2oW7fekNvsZXn081x2EcF8lTjJXDfK+3nViNfoSY7OAoZKEIF6HTYOPwFmiDM+ZZXg== +"@tiptap/extension-superscript@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/extension-superscript/-/extension-superscript-2.4.0.tgz#804355cc3d1b991e2e346d33f2bfaee04dbcc770" + integrity sha512-s+GsbbERNQCn/hyaw5/82y3wHQ7o5byc/eFAKYo1p3p5eESlDaHY/xVYPt3CGOX2TJWZalgSFEFqBVdTSI8mUQ== -"@tiptap/extension-table-cell@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/extension-table-cell/-/extension-table-cell-2.1.14.tgz#fddcb425485e9b28ffa9873e79e27dde5ce0bf44" - integrity sha512-4cnT35wA/O33H/UTOJUiZJFe0QjHfz8vOVjvkbeYOxcuo5Ww0Ro1D6RWU70fdAdkFccFJZ5UtqG9RcZi+JkNWA== +"@tiptap/extension-table-cell@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/extension-table-cell/-/extension-table-cell-2.4.0.tgz#048d869acbf6cfbcd31076adf8130ffd679990a7" + integrity sha512-zylResMWLvV17Z6+GEDjvvl+YpJqJhNMyJsZPZNx/72OcNCDN3p2d6RGFwhpnCpdzZDD6LGaIgWaTj9oeg53SA== -"@tiptap/extension-table-header@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/extension-table-header/-/extension-table-header-2.1.14.tgz#540cc2a7312f5bd6b13076eea11be608555dfacc" - integrity sha512-hg57IePDTGcr9GEFY5g201DreuXv3MZYp6TjqDGF/O48Yy2v22X+Baaa/SyW9WKPLPInAXBp2f8/2YSBKTuwLg== +"@tiptap/extension-table-header@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/extension-table-header/-/extension-table-header-2.4.0.tgz#618a86bc5e66149661129b7e8fbe2fd363882c2d" + integrity sha512-FZCOyJHSFsMTCfBh49J1DlwgpUIM5Ivpr57Za8FVvUkk8RKUIOKpNsZqxE+Wrw+2Bvy5H4X7Azb588x0NDqfOQ== -"@tiptap/extension-table-row@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/extension-table-row/-/extension-table-row-2.1.14.tgz#42968b0eca9f45f646d5c922818590d1365271b2" - integrity sha512-TE1qLztFerqKbm+ZkR+4tN24ZI6EFB99bYQ7QUaw5v1ioyL4QfDny2vSePKmjNObmgmFNl8I4hBqpuzYq9CzhQ== +"@tiptap/extension-table-row@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/extension-table-row/-/extension-table-row-2.4.0.tgz#751ecd4ce49ebe1ccdea153f27c3a61e4449cfd4" + integrity sha512-K4FDI4YzyLWZbhIZYYL15uqs6M3QsPZGTpTdkSaxcKMLholcskDSHhJmySxnrjI0+JNAtyIiqlWBfA1/9Zyhng== -"@tiptap/extension-table@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/extension-table/-/extension-table-2.1.14.tgz#c50e403c43fa5623088cf5a2cdf11adf180c63d8" - integrity sha512-e/idEukzXSThGKyRHxIaK3zqwLCaZMvm0Xcv2D8X2rnQTRIWr4ZR1+zCgwysFAUT26aDYfMUfmx2kAmuNNdLsg== +"@tiptap/extension-table@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/extension-table/-/extension-table-2.4.0.tgz#a29bb933a10ddbd9469263df0c7527ae1fa1de00" + integrity sha512-ceIUnPSqVCb+qC0XZSgApoG3dL3MRvWrGl1nIMxEqPgMsD/MP6MsYV1Lx/GmtdUlEEsV1624cGTBiRzeCuWkZA== -"@tiptap/extension-task-item@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/extension-task-item/-/extension-task-item-2.1.14.tgz#6e30bf3e02885e3fa978a94d83c92c80d47d1dc2" - integrity sha512-P5/Z1cARREnvpFa3gGvFMUm++OJ4RBS/9NVfwKmfg4Y71/0ZbLpaYrq4TKSa8Zg/lR1Ybx7Y1T9agmDu5D5S1g== +"@tiptap/extension-task-item@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/extension-task-item/-/extension-task-item-2.4.0.tgz#33227e72fcffdf087446f88cdb7a10feab4c2087" + integrity sha512-x40vdHnmDiBbA2pjWR/92wVGb6jT13Nk2AhRUI/oP/r4ZGKpTypoB7heDnvLBgH0Y5a51dFqU+G1SFFL30u5uA== -"@tiptap/extension-task-list@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/extension-task-list/-/extension-task-list-2.1.14.tgz#4c6d12c9d45673bc0dd4e32031b4afa1fe041049" - integrity sha512-yI5vd6L0UC0aJvujjmzCnYfx9K8FExI/kVHd/+AlxGQwG90+XAfj6Tw93GyIu7DhGRq/Goek1Mt+RC09sw4AHQ== +"@tiptap/extension-task-list@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/extension-task-list/-/extension-task-list-2.4.0.tgz#61a500fe4a89d5c789ad4fb64c8d7eeedfe26b63" + integrity sha512-vmUB3wEJU81QbiHUygBlselQW8YIW8/85UTwANvWx8+KEWyM7EUF4utcm5R2UobIprIcWb4hyVkvW/5iou25gg== -"@tiptap/extension-text@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/extension-text/-/extension-text-2.1.14.tgz#a781c68fe348bdd08730e727f2380295dc190260" - integrity sha512-Z5g+SlWqnK2loIwqkg2LzsVKVCiMyUfDD8IhNJsny0BRbWKFs4SKPCkAcyCxLK2h8Jm/BG6PyfGHsF/2wx7I3Q== +"@tiptap/extension-text@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/extension-text/-/extension-text-2.4.0.tgz#a3a5f45a9856d513e574f24e2c9b6028273f8eb3" + integrity sha512-LV0bvE+VowE8IgLca7pM8ll7quNH+AgEHRbSrsI3SHKDCYB9gTHMjWaAkgkUVaO1u0IfCrjnCLym/PqFKa+vvg== -"@tiptap/pm@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/pm/-/pm-2.1.14.tgz#b504120adfa428e4eb0526d5ea2b4ba5ed55400b" - integrity sha512-UuHqLDFPEPVLk4iopdHFpnn9KPNmbwQ8M0lnDRK1a9ZBheQpdTj6mQYFteYGKdqJpfcbhLHvmYl8nthfzlXGYw== +"@tiptap/pm@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/pm/-/pm-2.4.0.tgz#f6fe81d24569da584658d2e8a3a378aea3619fb3" + integrity sha512-B1HMEqGS4MzIVXnpgRZDLm30mxDWj51LkBT/if1XD+hj5gm8B9Q0c84bhvODX6KIs+c6z+zsY9VkVu8w9Yfgxg== dependencies: - prosemirror-changeset "^2.2.0" - prosemirror-collab "^1.3.0" - prosemirror-commands "^1.3.1" - prosemirror-dropcursor "^1.5.0" - prosemirror-gapcursor "^1.3.1" - prosemirror-history "^1.3.0" - prosemirror-inputrules "^1.2.0" - prosemirror-keymap "^1.2.0" - prosemirror-markdown "^1.10.1" - prosemirror-menu "^1.2.1" - prosemirror-model "^1.18.1" - prosemirror-schema-basic "^1.2.0" - prosemirror-schema-list "^1.2.2" - prosemirror-state "^1.4.1" - prosemirror-tables "^1.3.0" - prosemirror-trailing-node "^2.0.2" - prosemirror-transform "^1.7.0" - prosemirror-view "^1.28.2" + prosemirror-changeset "^2.2.1" + prosemirror-collab "^1.3.1" + prosemirror-commands "^1.5.2" + prosemirror-dropcursor "^1.8.1" + prosemirror-gapcursor "^1.3.2" + prosemirror-history "^1.3.2" + prosemirror-inputrules "^1.3.0" + prosemirror-keymap "^1.2.2" + prosemirror-markdown "^1.12.0" + prosemirror-menu "^1.2.4" + prosemirror-model "^1.19.4" + prosemirror-schema-basic "^1.2.2" + prosemirror-schema-list "^1.3.0" + prosemirror-state "^1.4.3" + prosemirror-tables "^1.3.5" + prosemirror-trailing-node "^2.0.7" + prosemirror-transform "^1.8.0" + prosemirror-view "^1.32.7" -"@tiptap/suggestion@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/suggestion/-/suggestion-2.1.14.tgz#baae04da4cb1cb9431f85cc90456185851d5b167" - integrity sha512-8jx+RYY4cZ3ZFmHDm4fPhHN6N8fwIgFnB6iBTbEh5Ra+0Bvh1q+Ek21+Ni92ORjmYz9Vy1e5xxJMyGNywRS5dw== +"@tiptap/suggestion@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/suggestion/-/suggestion-2.4.0.tgz#1926cde5f197d116baf7794f55bd971245540e5c" + integrity sha512-6dCkjbL8vIzcLWtS6RCBx0jlYPKf2Beuyq5nNLrDDZZuyJow5qJAY0eGu6Xomp9z0WDK/BYOxT4hHNoGMDkoAg== -"@tiptap/vue-2@^2.1.14": - version "2.1.14" - resolved "https://registry.yarnpkg.com/@tiptap/vue-2/-/vue-2-2.1.14.tgz#59acb020a0ace9946d6f78572ae8a7629826b934" - integrity sha512-7kisS73LLnFlmRe0T7o/FBlZghaBsZDty1qfAuS+TrhgW1o5wvCtm8Ogoomai2ExWK6Lh8k7E3nc2lDS03s/aw== +"@tiptap/vue-2@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tiptap/vue-2/-/vue-2-2.4.0.tgz#ce5fcc9e8011782c9a92be1b3b51524523226c47" + integrity sha512-1XMkPAbzn3m5moP2D8IoYP2Kl4bkC3WWa38TJTEtJf8YOgia5nakHct+c7QAjN37j0TArbPa5MxXddKp/CqyRA== dependencies: - "@tiptap/extension-bubble-menu" "^2.1.14" - "@tiptap/extension-floating-menu" "^2.1.14" + "@tiptap/extension-bubble-menu" "^2.4.0" + "@tiptap/extension-floating-menu" "^2.4.0" vue-ts-types "^1.6.0" "@tootallnate/once@2": @@ -3126,16 +3091,6 @@ resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA== -"@types/object.omit@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/object.omit/-/object.omit-3.0.0.tgz#0d31e1208eac8fe2ad5c9499a1016a8273bbfafc" - integrity sha512-I27IoPpH250TUzc9FzXd0P1BV/BMJuzqD3jOz98ehf9dQqGkxlq+hO1bIqZGWqCg5bVOy0g4AUVJtnxe0klDmw== - -"@types/object.pick@^1.3.1": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@types/object.pick/-/object.pick-1.3.2.tgz#9eb28118240ad8f658b9c9c6caf35359fdb37150" - integrity sha512-sn7L+qQ6RLPdXRoiaE7bZ/Ek+o4uICma/lBFPyJEKDTPTBP1W8u0c4baj3EiS4DiqLs+Hk+KUGvMVJtAw3ePJg== - "@types/parse5@^5": version "5.0.0" resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.0.tgz#9ae2106efc443d7c1e26570aa8247828c9c80f11" @@ -3210,11 +3165,6 @@ resolved "https://registry.yarnpkg.com/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz#9aa30c04db212a9a0649d6ae6fd50accc40748a1" integrity sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ== -"@types/throttle-debounce@^2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@types/throttle-debounce/-/throttle-debounce-2.1.0.tgz#1c3df624bfc4b62f992d3012b84c56d41eab3776" - integrity sha512-5eQEtSCoESnh2FsiLTxE121IiE60hnMqcb435fShf4bpLRjEu1Eoekht23y6zXS9Ts3l+Szu3TARnTsA0GkOkQ== - "@types/tough-cookie@*": version "4.0.2" resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.2.tgz#6286b4c7228d58ab7866d19716f3696e03a09397" @@ -4646,11 +4596,6 @@ canvas-confetti@^1.4.0: resolved "https://registry.yarnpkg.com/canvas-confetti/-/canvas-confetti-1.4.0.tgz#840f6db4a566f8f32abe28c00dcd82acf39c92bd" integrity sha512-S18o4Y9PqI/uabdlT/jI3MY7XBJjNxnfapFIkjkMwpz6qNxLFZOm2b22OMf4ZYDL9lpNWI+Ih4fEMVPwO1KHFQ== -case-anything@^2.1.10: - version "2.1.10" - resolved "https://registry.yarnpkg.com/case-anything/-/case-anything-2.1.10.tgz#d18a6ca968d54ec3421df71e3e190f3bced23410" - integrity sha512-JczJwVrCP0jPKh05McyVsuOg6AYosrB9XWZKbQzXeDAm2ClE/PJE/BcrrQrVyGYH7Jg8V/LDupmyL4kFlVsVFQ== - ccount@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/ccount/-/ccount-2.0.1.tgz#17a3bf82302e0870d6da43a01311a8bc02a3ecf5" @@ -5850,11 +5795,6 @@ dagre-d3-es@7.0.10: d3 "^7.8.2" lodash-es "^4.17.21" -dash-get@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/dash-get/-/dash-get-1.0.2.tgz#4c9e9ad5ef04c4bf9d3c9a451f6f7997298dcc7c" - integrity sha512-4FbVrHDwfOASx7uQVxeiCTo7ggSdYZbqs8lH+WU6ViypPlDbe9y6IP5VVUDQBv9DcnyaiPT5XT0UWHgJ64zLeQ== - data-urls@^3.0.1: version "3.0.2" resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-3.0.2.tgz#9cf24a477ae22bcef5cd5f6f0bfbc1d2d3be9143" @@ -8406,7 +8346,7 @@ is-extendable@^0.1.0, is-extendable@^0.1.1: resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= -is-extendable@^1.0.0, is-extendable@^1.0.1: +is-extendable@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== @@ -9670,11 +9610,6 @@ make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0: dependencies: semver "^6.0.0" -make-error@^1.3.6: - version "1.3.6" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== - makeerror@1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" @@ -9694,7 +9629,7 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" -markdown-it@14.0.0: +markdown-it@14.0.0, markdown-it@^14.0.0: version "14.0.0" resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-14.0.0.tgz#b4b2ddeb0f925e88d981f84c183b59bac9e3741b" integrity sha512-seFjF0FIcPt4P9U39Bq1JYblX0KZCjDLFFQPHpL5AzHpqPEKtosxmdq/LTVZnjfH7tjt9BxStm+wXcDBNuYmzw== @@ -10983,13 +10918,6 @@ object.groupby@^1.0.1: es-abstract "^1.22.1" get-intrinsic "^1.2.1" -object.omit@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-3.0.0.tgz#0e3edc2fce2ba54df5577ff529f6d97bd8a522af" - integrity sha512-EO+BCv6LJfu+gBIF3ggLicFebFLN5zqzz/WWJlMFfkMyGth+oBkhxzDl0wx2W4GkLzuQs/FsSkXZb2IMWQqmBQ== - dependencies: - is-extendable "^1.0.0" - object.pick@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" @@ -11629,74 +11557,75 @@ property-information@^6.0.0: resolved "https://registry.yarnpkg.com/property-information/-/property-information-6.1.1.tgz#5ca85510a3019726cb9afed4197b7b8ac5926a22" integrity sha512-hrzC564QIl0r0vy4l6MvRLhafmUowhO/O3KgVSoXIbbA2Sz4j8HGpJc6T2cubRVwMwpdiG/vKGfhT4IixmKN9w== -prosemirror-changeset@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/prosemirror-changeset/-/prosemirror-changeset-2.2.0.tgz#22c05da271a118be40d3e339fa2cace789b1254b" - integrity sha512-QM7ohGtkpVpwVGmFb8wqVhaz9+6IUXcIQBGZ81YNAKYuHiFJ1ShvSzab4pKqTinJhwciZbrtBEk/2WsqSt2PYg== +prosemirror-changeset@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/prosemirror-changeset/-/prosemirror-changeset-2.2.1.tgz#dae94b63aec618fac7bb9061648e6e2a79988383" + integrity sha512-J7msc6wbxB4ekDFj+n9gTW/jav/p53kdlivvuppHsrZXCaQdVgRghoZbSS3kwrRyAstRVQ4/+u5k7YfLgkkQvQ== dependencies: prosemirror-transform "^1.0.0" -prosemirror-collab@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/prosemirror-collab/-/prosemirror-collab-1.3.0.tgz#601d33473bf72e6c43041a54b860c84c60b37769" - integrity sha512-+S/IJ69G2cUu2IM5b3PBekuxs94HO1CxJIWOFrLQXUaUDKL/JfBx+QcH31ldBlBXyDEUl+k3Vltfi1E1MKp2mA== +prosemirror-collab@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/prosemirror-collab/-/prosemirror-collab-1.3.1.tgz#0e8c91e76e009b53457eb3b3051fb68dad029a33" + integrity sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ== dependencies: prosemirror-state "^1.0.0" -prosemirror-commands@^1.0.0, prosemirror-commands@^1.3.1: - version "1.5.0" - resolved "https://registry.yarnpkg.com/prosemirror-commands/-/prosemirror-commands-1.5.0.tgz#d10efece1647c1d984fef6f65d52fdc77785560b" - integrity sha512-zL0Fxbj3fh71GPNHn5YdYgYGX2aU2XLecZYk2ekEF0oOD259HcXtM+96VjPVi5o3h4sGUdDfEEhGiREXW6U+4A== +prosemirror-commands@^1.0.0, prosemirror-commands@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/prosemirror-commands/-/prosemirror-commands-1.5.2.tgz#e94aeea52286f658cd984270de9b4c3fff580852" + integrity sha512-hgLcPaakxH8tu6YvVAaILV2tXYsW3rAdDR8WNkeKGcgeMVQg3/TMhPdVoh7iAmfgVjZGtcOSjKiQaoeKjzd2mQ== dependencies: prosemirror-model "^1.0.0" prosemirror-state "^1.0.0" prosemirror-transform "^1.0.0" -prosemirror-dropcursor@^1.5.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/prosemirror-dropcursor/-/prosemirror-dropcursor-1.7.0.tgz#a846ba49414dcd99cf8fc8bb26e4f9f24b8f09d0" - integrity sha512-vzab/iPd3CjWILFv6WJz4+BlOwCywOcAGhvY5G/66OYPcaZehN8IVbGtHCV3oyhXk2yAA67nwMv/oNMvBV9k1A== +prosemirror-dropcursor@^1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/prosemirror-dropcursor/-/prosemirror-dropcursor-1.8.1.tgz#49b9fb2f583e0d0f4021ff87db825faa2be2832d" + integrity sha512-M30WJdJZLyXHi3N8vxN6Zh5O8ZBbQCz0gURTfPmTIBNQ5pxrdU7A58QkNqfa98YEjSAL1HUyyU34f6Pm5xBSGw== dependencies: prosemirror-state "^1.0.0" prosemirror-transform "^1.1.0" prosemirror-view "^1.1.0" -prosemirror-gapcursor@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/prosemirror-gapcursor/-/prosemirror-gapcursor-1.3.1.tgz#8cfd874592e4504d63720e14ed680c7866e64554" - integrity sha512-GKTeE7ZoMsx5uVfc51/ouwMFPq0o8YrZ7Hx4jTF4EeGbXxBveUV8CGv46mSHuBBeXGmvu50guoV2kSnOeZZnUA== +prosemirror-gapcursor@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/prosemirror-gapcursor/-/prosemirror-gapcursor-1.3.2.tgz#5fa336b83789c6199a7341c9493587e249215cb4" + integrity sha512-wtjswVBd2vaQRrnYZaBCbyDqr232Ed4p2QPtRIUK5FuqHYKGWkEwl08oQM4Tw7DOR0FsasARV5uJFvMZWxdNxQ== dependencies: prosemirror-keymap "^1.0.0" prosemirror-model "^1.0.0" prosemirror-state "^1.0.0" prosemirror-view "^1.0.0" -prosemirror-history@^1.0.0, prosemirror-history@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/prosemirror-history/-/prosemirror-history-1.3.0.tgz#bf5a1ff7759aca759ddf0c722c2fa5b14fb0ddc1" - integrity sha512-qo/9Wn4B/Bq89/YD+eNWFbAytu6dmIM85EhID+fz9Jcl9+DfGEo8TTSrRhP15+fFEoaPqpHSxlvSzSEbmlxlUA== +prosemirror-history@^1.0.0, prosemirror-history@^1.3.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/prosemirror-history/-/prosemirror-history-1.4.0.tgz#1edbce630aaf21b808e5a5cd798a09976ecb1827" + integrity sha512-UUiGzDVcqo1lovOPdi9YxxUps3oBFWAIYkXLu3Ot+JPv1qzVogRbcizxK3LhHmtaUxclohgiOVesRw5QSlMnbQ== dependencies: prosemirror-state "^1.2.2" prosemirror-transform "^1.0.0" + prosemirror-view "^1.31.0" rope-sequence "^1.3.0" -prosemirror-inputrules@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/prosemirror-inputrules/-/prosemirror-inputrules-1.2.0.tgz#476dde2dc244050b3aca00cf58a82adfad6749e7" - integrity sha512-eAW/M/NTSSzpCOxfR8Abw6OagdG0MiDAiWHQMQveIsZtoKVYzm0AflSPq/ymqJd56/Su1YPbwy9lM13wgHOFmQ== +prosemirror-inputrules@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/prosemirror-inputrules/-/prosemirror-inputrules-1.4.0.tgz#ef1519bb2cb0d1e0cec74bad1a97f1c1555068bb" + integrity sha512-6ygpPRuTJ2lcOXs9JkefieMst63wVJBgHZGl5QOytN7oSZs3Co/BYbc3Yx9zm9H37Bxw8kVzCnDsihsVsL4yEg== dependencies: prosemirror-state "^1.0.0" prosemirror-transform "^1.0.0" -prosemirror-keymap@^1.0.0, prosemirror-keymap@^1.1.2, prosemirror-keymap@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/prosemirror-keymap/-/prosemirror-keymap-1.2.1.tgz#3839e7db66cecddae7451f4246e73bdd8489be1d" - integrity sha512-kVK6WGC+83LZwuSJnuCb9PsADQnFZllt94qPP3Rx/vLcOUV65+IbBeH2nS5cFggPyEVJhGkGrgYFRrG250WhHQ== +prosemirror-keymap@^1.0.0, prosemirror-keymap@^1.1.2, prosemirror-keymap@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/prosemirror-keymap/-/prosemirror-keymap-1.2.2.tgz#14a54763a29c7b2704f561088ccf3384d14eb77e" + integrity sha512-EAlXoksqC6Vbocqc0GtzCruZEzYgrn+iiGnNjsJsH4mrnIGex4qbLdWWNza3AW5W36ZRrlBID0eM6bdKH4OStQ== dependencies: prosemirror-state "^1.0.0" w3c-keyname "^2.2.0" -prosemirror-markdown@1.11.2, prosemirror-markdown@^1.10.1: +prosemirror-markdown@1.11.2: version "1.11.2" resolved "https://registry.yarnpkg.com/prosemirror-markdown/-/prosemirror-markdown-1.11.2.tgz#f6e529e669d11fa3eec859e93c0d2c91788d6c80" integrity sha512-Eu5g4WPiCdqDTGhdSsG9N6ZjACQRYrsAkrF9KYfdMaCmjIApH75aVncsWYOJvEk2i1B3i8jZppv3J/tnuHGiUQ== @@ -11704,52 +11633,60 @@ prosemirror-markdown@1.11.2, prosemirror-markdown@^1.10.1: markdown-it "^13.0.1" prosemirror-model "^1.0.0" -prosemirror-menu@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/prosemirror-menu/-/prosemirror-menu-1.2.1.tgz#94d99a8547b7ba5680c20e9c497ce19846ce3b2c" - integrity sha512-sBirXxVfHalZO4f1ZS63WzewINK4182+7dOmoMeBkqYO8wqMBvBS7wQuwVOHnkMWPEh0+N0LJ856KYUN+vFkmQ== +prosemirror-markdown@^1.12.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/prosemirror-markdown/-/prosemirror-markdown-1.12.0.tgz#d2de09d37897abf7adb6293d925ff132dac5b0a6" + integrity sha512-6F5HS8Z0HDYiS2VQDZzfZP6A0s/I0gbkJy8NCzzDMtcsz3qrfqyroMMeoSjAmOhDITyon11NbXSzztfKi+frSQ== + dependencies: + markdown-it "^14.0.0" + prosemirror-model "^1.0.0" + +prosemirror-menu@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/prosemirror-menu/-/prosemirror-menu-1.2.4.tgz#3cfdc7c06d10f9fbd1bce29082c498bd11a0a79a" + integrity sha512-S/bXlc0ODQup6aiBbWVsX/eM+xJgCTAfMq/nLqaO5ID/am4wS0tTCIkzwytmao7ypEtjj39i7YbJjAgO20mIqA== dependencies: crelt "^1.0.0" prosemirror-commands "^1.0.0" prosemirror-history "^1.0.0" prosemirror-state "^1.0.0" -prosemirror-model@^1.0.0, prosemirror-model@^1.16.0, prosemirror-model@^1.18.1, prosemirror-model@^1.19.0, prosemirror-model@^1.8.1: - version "1.19.0" - resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.19.0.tgz#d7ad9a65ada0bb12196f64fe0dd4fc392c841c29" - integrity sha512-/CvFGJnwc41EJSfDkQLly1cAJJJmBpZwwUJtwZPTjY2RqZJfM8HVbCreOY/jti8wTRbVyjagcylyGoeJH/g/3w== +prosemirror-model@^1.0.0, prosemirror-model@^1.19.0, prosemirror-model@^1.19.4, prosemirror-model@^1.20.0, prosemirror-model@^1.21.0, prosemirror-model@^1.8.1: + version "1.21.0" + resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.21.0.tgz#2d69ed04b4e7c441c3eb87c1c964fab4f9b217df" + integrity sha512-zLpS1mVCZLA7VTp82P+BfMiYVPcX1/z0Mf3gsjKZtzMWubwn2pN7CceMV0DycjlgE5JeXPR7UF4hJPbBV98oWA== dependencies: orderedmap "^2.0.0" -prosemirror-schema-basic@^1.0.0, prosemirror-schema-basic@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/prosemirror-schema-basic/-/prosemirror-schema-basic-1.2.1.tgz#a5a137a6399d1a829873332117d2fe8131d291d0" - integrity sha512-vYBdIHsYKSDIqYmPBC7lnwk9DsKn8PnVqK97pMYP5MLEDFqWIX75JiaJTzndBii4bRuNqhC2UfDOfM3FKhlBHg== +prosemirror-schema-basic@^1.0.0, prosemirror-schema-basic@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/prosemirror-schema-basic/-/prosemirror-schema-basic-1.2.2.tgz#6695f5175e4628aab179bf62e5568628b9cfe6c7" + integrity sha512-/dT4JFEGyO7QnNTe9UaKUhjDXbTNkiWTq/N4VpKaF79bBjSExVV2NXmJpcM7z/gD7mbqNjxbmWW5nf1iNSSGnw== dependencies: prosemirror-model "^1.19.0" -prosemirror-schema-list@^1.0.0, prosemirror-schema-list@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/prosemirror-schema-list/-/prosemirror-schema-list-1.2.2.tgz#bafda37b72367d39accdcaf6ddf8fb654a16e8e5" - integrity sha512-rd0pqSDp86p0MUMKG903g3I9VmElFkQpkZ2iOd3EOVg1vo5Cst51rAsoE+5IPy0LPXq64eGcCYlW1+JPNxOj2w== +prosemirror-schema-list@^1.0.0, prosemirror-schema-list@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/prosemirror-schema-list/-/prosemirror-schema-list-1.3.0.tgz#05374702cf35a3ba5e7ec31079e355a488d52519" + integrity sha512-Hz/7gM4skaaYfRPNgr421CU4GSwotmEwBVvJh5ltGiffUJwm7C8GfN/Bc6DR1EKEp5pDKhODmdXXyi9uIsZl5A== dependencies: prosemirror-model "^1.0.0" prosemirror-state "^1.0.0" - prosemirror-transform "^1.0.0" + prosemirror-transform "^1.7.3" -prosemirror-state@^1.0.0, prosemirror-state@^1.2.2, prosemirror-state@^1.3.1, prosemirror-state@^1.4.1: - version "1.4.2" - resolved "https://registry.yarnpkg.com/prosemirror-state/-/prosemirror-state-1.4.2.tgz#f93bd8a33a4454efab917ba9b738259d828db7e5" - integrity sha512-puuzLD2mz/oTdfgd8msFbe0A42j5eNudKAAPDB0+QJRw8cO1ygjLmhLrg9RvDpf87Dkd6D4t93qdef00KKNacQ== +prosemirror-state@^1.0.0, prosemirror-state@^1.2.2, prosemirror-state@^1.3.1, prosemirror-state@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/prosemirror-state/-/prosemirror-state-1.4.3.tgz#94aecf3ffd54ec37e87aa7179d13508da181a080" + integrity sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q== dependencies: prosemirror-model "^1.0.0" prosemirror-transform "^1.0.0" prosemirror-view "^1.27.0" -prosemirror-tables@^1.3.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/prosemirror-tables/-/prosemirror-tables-1.3.2.tgz#ca208c6a55d510af14b652d23e800e00ba6bebd4" - integrity sha512-/9JTeN6s58Zq66HXaxP6uf8PAmc7XXKZFPlOGVtLvxEd6xBP6WtzaJB9wBjiGUzwbdhdMEy7V62yuHqk/3VrnQ== +prosemirror-tables@^1.3.5: + version "1.3.7" + resolved "https://registry.yarnpkg.com/prosemirror-tables/-/prosemirror-tables-1.3.7.tgz#9d296bd432d2bc7dca90f14e5c3b5c5f61277f7a" + integrity sha512-oEwX1wrziuxMtwFvdDWSFHVUWrFJWt929kVVfHvtTi8yvw+5ppxjXZkMG/fuTdFo+3DXyIPSKfid+Be1npKXDA== dependencies: prosemirror-keymap "^1.1.2" prosemirror-model "^1.8.1" @@ -11766,29 +11703,27 @@ prosemirror-test-builder@^1.1.1: prosemirror-schema-basic "^1.0.0" prosemirror-schema-list "^1.0.0" -prosemirror-trailing-node@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/prosemirror-trailing-node/-/prosemirror-trailing-node-2.0.3.tgz#213fc0e545a434ff3c37b5218a0de69561bf3892" - integrity sha512-lGrjMrn97KWkjQSW/FjdvnhJmqFACmQIyr6lKYApvHitDnKsCoZz6XzrHB7RZYHni/0NxQmZ01p/2vyK2SkvaA== +prosemirror-trailing-node@^2.0.7: + version "2.0.8" + resolved "https://registry.yarnpkg.com/prosemirror-trailing-node/-/prosemirror-trailing-node-2.0.8.tgz#233ddcbda72de06f9b5d758d2a65a8cac482ea10" + integrity sha512-ujRYhSuhQb1Jsarh1IHqb2KoSnRiD7wAMDGucP35DN7j5af6X7B18PfdPIrbwsPTqIAj0fyOvxbuPsWhNvylmA== dependencies: - "@babel/runtime" "^7.13.10" - "@remirror/core-constants" "^2.0.0" - "@remirror/core-helpers" "^2.0.1" + "@remirror/core-constants" "^2.0.2" escape-string-regexp "^4.0.0" -prosemirror-transform@^1.0.0, prosemirror-transform@^1.1.0, prosemirror-transform@^1.2.1, prosemirror-transform@^1.7.0: - version "1.7.1" - resolved "https://registry.yarnpkg.com/prosemirror-transform/-/prosemirror-transform-1.7.1.tgz#b516e818c3add0bdf960f4ca8ccb9d057a3ba21b" - integrity sha512-VteoifAfpt46z0yEt6Fc73A5OID9t/y2QIeR5MgxEwTuitadEunD/V0c9jQW8ziT8pbFM54uTzRLJ/nLuQjMxg== +prosemirror-transform@^1.0.0, prosemirror-transform@^1.1.0, prosemirror-transform@^1.2.1, prosemirror-transform@^1.7.3, prosemirror-transform@^1.8.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/prosemirror-transform/-/prosemirror-transform-1.9.0.tgz#81fd1fbd887929a95369e6dd3d240c23c19313f8" + integrity sha512-5UXkr1LIRx3jmpXXNKDhv8OyAOeLTGuXNwdVfg8x27uASna/wQkr9p6fD3eupGOi4PLJfbezxTyi/7fSJypXHg== dependencies: - prosemirror-model "^1.0.0" + prosemirror-model "^1.21.0" -prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3, prosemirror-view@^1.27.0, prosemirror-view@^1.28.2: - version "1.30.1" - resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.30.1.tgz#7cf0ae8dc8553a02c32961e82eca25079c4d8fc9" - integrity sha512-pZUfr7lICJkEY7XwzldAKrkflZDeIvnbfuu2RIS01N5NwJmR/dfZzDzJRzhb3SM2QtT/bM8b4Nnib8X3MGpAhA== +prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3, prosemirror-view@^1.27.0, prosemirror-view@^1.31.0, prosemirror-view@^1.32.7: + version "1.33.6" + resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.33.6.tgz#85804eb922411af8e300a07f4f376722b15900b9" + integrity sha512-zRLUNgLIQfd8IfGprsXxWTjdA8xEAFJe8cDNrOptj6Mop9sj+BMeVbJvceyAYCm5G2dOdT2prctH7K9dfnpIMw== dependencies: - prosemirror-model "^1.16.0" + prosemirror-model "^1.20.0" prosemirror-state "^1.0.0" prosemirror-transform "^1.1.0" @@ -13814,11 +13749,6 @@ type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== -type-fest@^2.0.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" - integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== - type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"