Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-07-28 00:09:28 +00:00
parent 9da482ecb8
commit 2d096b1a9b
76 changed files with 1306 additions and 1036 deletions

View File

@ -1,7 +1,7 @@
<script>
import { GlDropdown, GlDropdownItem, GlDropdownDivider } from '@gitlab/ui';
import { NodeViewWrapper, NodeViewContent } from '@tiptap/vue-2';
import { selectedRect as getSelectedRect } from 'prosemirror-tables';
import { selectedRect as getSelectedRect } from '@_ueberdosis/prosemirror-tables';
import { __ } from '~/locale';
const TABLE_CELL_HEADER = 'th';

View File

@ -1,3 +1,4 @@
import { lowlight } from 'lowlight/lib/core';
import { CodeBlockLowlight } from '@tiptap/extension-code-block-lowlight';
import { textblockTypeInputRule } from '@tiptap/core';
import { VueNodeViewRenderer } from '@tiptap/vue-2';
@ -66,4 +67,4 @@ export default CodeBlockLowlight.extend({
addNodeView() {
return new VueNodeViewRenderer(CodeBlockWrapper);
},
});
}).configure({ lowlight });

View File

@ -1,3 +1,4 @@
import { lowlight } from 'lowlight/lib/core';
import { textblockTypeInputRule } from '@tiptap/core';
import { PARSE_HTML_PRIORITY_HIGHEST } from '../constants';
import languageLoader from '../services/code_block_language_loader';
@ -10,6 +11,12 @@ export default CodeBlockHighlight.extend({
isolating: true,
addOptions() {
return {
lowlight,
};
},
addAttributes() {
return {
language: {

View File

@ -1,9 +1,16 @@
import { lowlight } from 'lowlight/lib/core';
import { PARSE_HTML_PRIORITY_HIGHEST } from '../constants';
import CodeBlockHighlight from './code_block_highlight';
export default CodeBlockHighlight.extend({
name: 'frontmatter',
addOptions() {
return {
lowlight,
};
},
addAttributes() {
return {
...this.parent?.(),

View File

@ -1,4 +1,3 @@
import { TextSelection } from 'prosemirror-state';
import { LOADING_CONTENT_EVENT, LOADING_SUCCESS_EVENT, LOADING_ERROR_EVENT } from '../constants';
/* eslint-disable no-underscore-dangle */
@ -59,7 +58,6 @@ export class ContentEditor {
async setSerializedContent(serializedContent) {
const { _tiptapEditor: editor, _eventHub: eventHub } = this;
const { doc, tr } = editor.state;
const selection = TextSelection.create(doc, 0, doc.content.size);
try {
eventHub.$emit(LOADING_CONTENT_EVENT);
@ -67,9 +65,7 @@ export class ContentEditor {
if (document) {
this._pristineDoc = document;
tr.setSelection(selection)
.replaceSelectionWith(document, false)
.setMeta('preventUpdate', true);
tr.replaceWith(0, doc.content.size, document).setMeta('preventUpdate', true);
editor.view.dispatch(tr);
}

View File

@ -1,6 +1,5 @@
import { Editor } from '@tiptap/vue-2';
import { isFunction } from 'lodash';
import { lowlight } from 'lowlight/lib/core';
import eventHubFactory from '~/helpers/event_hub_factory';
import { PROVIDE_SERIALIZER_OR_RENDERER_ERROR } from '../constants';
import Attachment from '../extensions/attachment';
@ -96,7 +95,7 @@ export const createContentEditor = ({
BulletList,
Code,
ColorChip,
CodeBlockHighlight.configure({ lowlight }),
CodeBlockHighlight,
DescriptionItem,
DescriptionList,
Details,
@ -110,7 +109,7 @@ export const createContentEditor = ({
FootnoteDefinition,
FootnoteReference,
FootnotesSection,
Frontmatter.configure({ lowlight }),
Frontmatter,
Gapcursor,
HardBreak,
Heading,
@ -127,7 +126,7 @@ export const createContentEditor = ({
MathInline,
OrderedList,
Paragraph,
PasteMarkdown.configure({ renderMarkdown, eventHub }),
PasteMarkdown,
Reference,
Sourcemap,
Strike,

View File

@ -0,0 +1,11 @@
/**
* This module replaces markdown-it with an empty function. markdown-it
* is a dependency of the prosemirror-markdown package. prosemirror-markdown
* uses markdown-it to parse markdown and produce an AST. However, the
* features that use prosemirror-markdown in the GitLab application do not
* require markdown parsing.
*
* Replacing markdown-it with this empty function removes unnecessary javascript
* from the production builds.
*/
export default () => {};

View File

@ -1,3 +1 @@
// Import from `src/to_markdown` to avoid unnecessary bundling of unused libs
// https://gitlab.com/gitlab-org/gitlab/-/merge_requests/79859
export * from 'prosemirror-markdown/src/to_markdown';
export { MarkdownSerializer, defaultMarkdownSerializer } from 'prosemirror-markdown';

View File

@ -1,12 +1,24 @@
<script>
import { GlDropdown, GlDropdownItem, GlDropdownDivider, GlSearchBoxByType } from '@gitlab/ui';
import {
GlDropdown,
GlDropdownItem,
GlDropdownDivider,
GlSearchBoxByType,
GlSprintf,
GlLink,
} from '@gitlab/ui';
import { createAlert } from '~/flash';
import { __, sprintf } from '~/locale';
import { s__, sprintf } from '~/locale';
import { helpPagePath } from '~/helpers/help_page_helper';
import branchesQuery from '../queries/branches.query.graphql';
export const i18n = {
fetchBranchesError: __('An error occurred while fetching branches.'),
noMatch: __('No matching results'),
fetchBranchesError: s__('BranchRules|An error occurred while fetching branches.'),
noMatch: s__('BranchRules|No matching results'),
branchHelpText: s__(
'BranchRules|%{linkStart}Wildcards%{linkEnd} such as *-stable or production/* are supported.',
),
wildCardSearchHelp: s__('BranchRules|Create wildcard: %{searchTerm}'),
};
export default {
@ -17,6 +29,8 @@ export default {
GlDropdownItem,
GlDropdownDivider,
GlSearchBoxByType,
GlSprintf,
GlLink,
},
apollo: {
branchNames: {
@ -39,6 +53,10 @@ export default {
},
},
},
searchInputDelay: 250,
wildcardsHelpPath: helpPagePath('user/project/protected_branches', {
anchor: 'configure-multiple-protected-branches-by-using-a-wildcard',
}),
props: {
projectPath: {
type: String,
@ -58,7 +76,9 @@ export default {
},
computed: {
createButtonLabel() {
return sprintf(__('Create wildcard: %{searchTerm}'), { searchTerm: this.searchTerm });
return sprintf(this.$options.i18n.wildCardSearchHelp, {
searchTerm: this.searchTerm,
});
},
shouldRenderCreateButton() {
return this.searchTerm && !this.branchNames.includes(this.searchTerm);
@ -81,30 +101,37 @@ export default {
};
</script>
<template>
<gl-dropdown :text="value || branchNames[0]">
<gl-search-box-by-type
v-model.trim="searchTerm"
data-testid="branch-search"
debounce="250"
:is-loading="isLoading"
/>
<gl-dropdown-item
v-for="branch in branchNames"
:key="branch"
:is-checked="isSelected(branch)"
is-check-item
@click="selectBranch(branch)"
>
{{ branch }}
</gl-dropdown-item>
<gl-dropdown-item v-if="!branchNames.length && !isLoading" data-testid="no-data">{{
$options.i18n.noMatch
}}</gl-dropdown-item>
<template v-if="shouldRenderCreateButton">
<gl-dropdown-divider />
<gl-dropdown-item data-testid="create-wildcard-button" @click="createWildcard">
{{ createButtonLabel }}
<div>
<gl-dropdown :text="value || branchNames[0]" class="gl-w-full">
<gl-search-box-by-type
v-model.trim="searchTerm"
data-testid="branch-search"
:debounce="$options.searchInputDelay"
:is-loading="isLoading"
/>
<gl-dropdown-item
v-for="branch in branchNames"
:key="branch"
:is-checked="isSelected(branch)"
is-check-item
@click="selectBranch(branch)"
>
{{ branch }}
</gl-dropdown-item>
</template>
</gl-dropdown>
<gl-dropdown-item v-if="!branchNames.length && !isLoading" data-testid="no-data">{{
$options.i18n.noMatch
}}</gl-dropdown-item>
<template v-if="shouldRenderCreateButton">
<gl-dropdown-divider />
<gl-dropdown-item data-testid="create-wildcard-button" @click="createWildcard">
{{ createButtonLabel }}
</gl-dropdown-item>
</template>
</gl-dropdown>
<gl-sprintf :message="$options.i18n.branchHelpText">
<template #link="{ content }">
<gl-link :href="$options.wildcardsHelpPath">{{ content }}</gl-link>
</template>
</gl-sprintf>
</div>
</template>

View File

@ -0,0 +1,59 @@
<script>
import { GlSprintf, GlLink } from '@gitlab/ui';
import { s__ } from '~/locale';
import { helpPagePath } from '~/helpers/help_page_helper';
import PushProtections from './push_protections.vue';
import MergeProtections from './merge_protections.vue';
export const i18n = {
protections: s__('BranchRules|Protections'),
protectionsHelpText: s__(
'BranchRules|Keep stable branches secure and force developers to use merge requests. %{linkStart}What are protected branches?%{linkEnd}',
),
};
export default {
name: 'BranchProtections',
i18n,
components: {
GlSprintf,
GlLink,
PushProtections,
MergeProtections,
},
protectedBranchesHelpPath: helpPagePath('user/project/protected_branches'),
props: {
protections: {
type: Object,
required: true,
},
},
};
</script>
<template>
<div>
<h4 class="gl-border-t gl-pt-4">{{ $options.i18n.protections }}</h4>
<div data-testid="protections-help-text">
<gl-sprintf :message="$options.i18n.protectionsHelpText">
<template #link="{ content }">
<gl-link :href="$options.protectedBranchesHelpPath">{{ content }}</gl-link>
</template>
</gl-sprintf>
</div>
<push-protections
class="gl-mt-5"
:members-allowed-to-push="protections.membersAllowedToPush"
:allow-force-push="protections.allowForcePush"
v-on="$listeners"
/>
<merge-protections
:members-allowed-to-merge="protections.membersAllowedToMerge"
:require-code-owners-approval="protections.requireCodeOwnersApproval"
v-on="$listeners"
/>
</div>
</template>

View File

@ -0,0 +1,46 @@
<script>
import { GlFormGroup, GlFormCheckbox } from '@gitlab/ui';
import { s__ } from '~/locale';
export const i18n = {
allowedToMerge: s__('BranchRules|Allowed to merge'),
requireApprovalTitle: s__('BranchRules|Require approval from code owners.'),
requireApprovalHelpText: s__(
'BranchRules|Reject code pushes that change files listed in the CODEOWNERS file.',
),
};
export default {
name: 'BranchMergeProtections',
i18n,
components: {
GlFormGroup,
GlFormCheckbox,
},
props: {
membersAllowedToMerge: {
type: Array,
required: true,
},
requireCodeOwnersApproval: {
type: Boolean,
required: true,
},
},
};
</script>
<template>
<gl-form-group :label="$options.i18n.allowedToMerge">
<!-- TODO: add multi-select-dropdown (https://gitlab.com/gitlab-org/gitlab/-/issues/362212) -->
<gl-form-checkbox
class="gl-mt-5"
:checked="requireCodeOwnersApproval"
@change="$emit('change-require-code-owners-approval', $event)"
>
<span>{{ $options.i18n.requireApprovalTitle }}</span>
<template #help>{{ $options.i18n.requireApprovalHelpText }}</template>
</gl-form-checkbox>
</gl-form-group>
</template>

View File

@ -0,0 +1,52 @@
<script>
import { GlFormGroup, GlSprintf, GlLink, GlFormCheckbox } from '@gitlab/ui';
import { s__ } from '~/locale';
import { helpPagePath } from '~/helpers/help_page_helper';
export const i18n = {
allowedToPush: s__('BranchRules|Allowed to push'),
forcePushTitle: s__(
'BranchRules|Allow all users with push access to %{linkStart}force push%{linkEnd}.',
),
};
export default {
name: 'BranchPushProtections',
i18n,
components: {
GlFormGroup,
GlSprintf,
GlLink,
GlFormCheckbox,
},
forcePushHelpPath: helpPagePath('topics/git/git_rebase', { anchor: 'force-push' }),
props: {
membersAllowedToPush: {
type: Array,
required: true,
},
allowForcePush: {
type: Boolean,
required: true,
},
},
};
</script>
<template>
<gl-form-group :label="$options.i18n.allowedToPush">
<!-- TODO: add multi-select-dropdown (https://gitlab.com/gitlab-org/gitlab/-/issues/362212) -->
<gl-form-checkbox
class="gl-mt-5"
:checked="allowForcePush"
@change="$emit('change-allow-force-push', $event)"
>
<gl-sprintf :message="$options.i18n.forcePushTitle">
<template #link="{ content }">
<gl-link :href="$options.forcePushHelpPath">{{ content }}</gl-link>
</template>
</gl-sprintf>
</gl-form-checkbox>
</gl-form-group>
</template>

View File

@ -1,15 +1,18 @@
<script>
import { GlFormGroup } from '@gitlab/ui';
import { __ } from '~/locale';
import { s__ } from '~/locale';
import { getParameterByName } from '~/lib/utils/url_utility';
import BranchDropdown from './branch_dropdown.vue';
import Protections from './protections/index.vue';
export default {
name: 'RuleEdit',
i18n: {
branch: __('Branch'),
i18n: { branch: s__('BranchRules|Branch') },
components: {
BranchDropdown,
GlFormGroup,
Protections,
},
components: { BranchDropdown, GlFormGroup },
props: {
projectPath: {
type: String,
@ -19,20 +22,35 @@ export default {
data() {
return {
branch: getParameterByName('branch'),
protections: {
membersAllowedToPush: [],
allowForcePush: false,
membersAllowedToMerge: [],
requireCodeOwnersApproval: false,
},
};
},
};
</script>
<template>
<gl-form-group :label="$options.i18n.branch">
<branch-dropdown
id="branches"
v-model="branch"
class="gl-w-half"
:project-path="projectPath"
@createWildcard="branch = $event"
<div>
<gl-form-group :label="$options.i18n.branch">
<branch-dropdown
id="branches"
v-model="branch"
class="gl-w-half"
:project-path="projectPath"
@createWildcard="branch = $event"
/>
</gl-form-group>
<protections
:protections="protections"
@change-allowed-to-push-members="protections.membersAllowedToPush = $event"
@change-allow-force-push="protections.allowForcePush = $event"
@change-allowed-to-merge-members="protections.membersAllowedToMerge = $event"
@change-require-code-owners-approval="protections.requireCodeOwnersApproval = $event"
/>
</gl-form-group>
<!-- TODO - Add branch protections (https://gitlab.com/gitlab-org/gitlab/-/issues/362212) -->
</div>
</template>

View File

@ -1,6 +1,6 @@
= render Pajamas::AlertComponent.new(title: _('Too many changes to show.'),
variant: :warning,
alert_options: { class: 'gl-mb-5' }) do |c|
alert_options: { class: 'gl-mb-5', data: { testid: "too-many-changes-alert" } }) do |c|
= c.body do
= message

View File

@ -24,29 +24,90 @@ module StorageHelper
_("Repository: %{counter_repositories} / Wikis: %{counter_wikis} / Build Artifacts: %{counter_build_artifacts} / Pipeline Artifacts: %{counter_pipeline_artifacts} / LFS: %{counter_lfs_objects} / Snippets: %{counter_snippets} / Packages: %{counter_packages} / Uploads: %{counter_uploads}") % counters
end
def storage_enforcement_banner_info(namespace)
root_ancestor = namespace.root_ancestor
def storage_enforcement_banner_info(context)
root_ancestor = context.root_ancestor
return unless can?(current_user, :maintain_namespace, root_ancestor)
return if root_ancestor.paid?
return unless future_enforcement_date?(root_ancestor)
return if user_dismissed_storage_enforcement_banner?(root_ancestor)
return unless ::Feature.enabled?(:namespace_storage_limit_show_preenforcement_banner, root_ancestor)
return unless should_show_storage_enforcement_banner?(context, current_user, root_ancestor)
text_args = storage_enforcement_banner_text_args(root_ancestor, context)
text_paragraph_2 = if root_ancestor.user_namespace?
html_escape_once(s_("UsageQuota|The namespace is currently using %{strong_start}%{used_storage}%{strong_end} of namespace storage. " \
"View and manage your usage from %{strong_start}User settings &gt; Usage quotas%{strong_end}. %{docs_link_start}Learn more%{link_end} " \
"about how to reduce your storage.")).html_safe % text_args[:p2]
else
html_escape_once(s_("UsageQuota|The namespace is currently using %{strong_start}%{used_storage}%{strong_end} of namespace storage. " \
"View and manage your usage from %{strong_start}Group settings &gt; Usage quotas%{strong_end}. %{docs_link_start}Learn more%{link_end} " \
"about how to reduce your storage.")).html_safe % text_args[:p2]
end
{
text: html_escape_once(s_("UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. " \
"You are currently using %{used_storage} of namespace storage. " \
"View and manage your usage from %{strong_start}%{namespace_type} settings &gt; Usage quotas%{strong_end}.")).html_safe %
{ storage_enforcement_date: root_ancestor.storage_enforcement_date, used_storage: storage_counter(root_ancestor.root_storage_statistics&.storage_size || 0), strong_start: "<strong>".html_safe, strong_end: "</strong>".html_safe, namespace_type: root_ancestor.type },
text_paragraph_1: html_escape_once(s_("UsageQuota|Effective %{storage_enforcement_date}, %{announcement_link_start}namespace storage limits will apply%{link_end} " \
"to the %{strong_start}%{namespace_name}%{strong_end} namespace. %{extra_message}" \
"View the %{rollout_link_start}rollout schedule for this change%{link_end}.")).html_safe % text_args[:p1],
text_paragraph_2: text_paragraph_2,
text_paragraph_3: html_escape_once(s_("UsageQuota|See our %{faq_link_start}FAQ%{link_end} for more information.")).html_safe % text_args[:p3],
variant: 'warning',
namespace_id: root_ancestor.id,
callouts_path: root_ancestor.user_namespace? ? callouts_path : group_callouts_path,
callouts_feature_name: storage_enforcement_banner_user_callouts_feature_name(root_ancestor),
learn_more_link: link_to(_('Learn more.'), help_page_path('/'), rel: 'noopener noreferrer', target: '_blank')
callouts_feature_name: storage_enforcement_banner_user_callouts_feature_name(root_ancestor)
}
end
private
def should_show_storage_enforcement_banner?(context, current_user, root_ancestor)
return false unless user_allowed_storage_enforcement_banner?(context, current_user, root_ancestor)
return false if root_ancestor.paid?
return false unless future_enforcement_date?(root_ancestor)
return false if user_dismissed_storage_enforcement_banner?(root_ancestor)
::Feature.enabled?(:namespace_storage_limit_show_preenforcement_banner, root_ancestor)
end
def user_allowed_storage_enforcement_banner?(context, current_user, root_ancestor)
return can?(current_user, :maintainer_access, context) unless context.respond_to?(:user_namespace?) && context.user_namespace?
can?(current_user, :owner_access, context)
end
def storage_enforcement_banner_text_args(root_ancestor, context)
strong_tags = {
strong_start: "<strong>".html_safe,
strong_end: "</strong>".html_safe
}
extra_message = if context.is_a?(Project)
html_escape_once(s_("UsageQuota|The %{strong_start}%{context_name}%{strong_end} project will be affected by this. "))
.html_safe % strong_tags.merge(context_name: context.name)
elsif !context.root?
html_escape_once(s_("UsageQuota|The %{strong_start}%{context_name}%{strong_end} group will be affected by this. "))
.html_safe % strong_tags.merge(context_name: context.name)
else
''
end
{
p1: {
storage_enforcement_date: root_ancestor.storage_enforcement_date,
namespace_name: root_ancestor.name,
extra_message: extra_message,
announcement_link_start: '<a href="%{url}" >'.html_safe % { url: "#{Gitlab::Saas.community_forum_url}/t/gitlab-introduces-storage-and-transfer-limits-for-users-on-saas/69883" },
rollout_link_start: '<a href="%{url}" >'.html_safe % { url: help_page_path('user/usage_quotas', anchor: 'tbd') },
link_end: "</a>".html_safe
}.merge(strong_tags),
p2: {
used_storage: storage_counter(root_ancestor.root_storage_statistics&.storage_size || 0),
docs_link_start: '<a href="%{url}" >'.html_safe % { url: help_page_path('user/usage_quotas', anchor: 'manage-your-storage-usage') },
link_end: "</a>".html_safe
}.merge(strong_tags),
p3: {
faq_link_start: '<a href="%{url}" >'.html_safe % { url: "#{Gitlab::Saas.about_pricing_url}faq-efficient-free-tier/#storage-and-transfer-limits-on-gitlab-saas-free-tier" },
link_end: "</a>".html_safe
}
}
end
def storage_enforcement_banner_user_callouts_feature_name(namespace)
"storage_enforcement_banner_#{storage_enforcement_banner_threshold(namespace)}_enforcement_threshold"
end

View File

@ -40,6 +40,10 @@ class Namespace < ApplicationRecord
PATH_TRAILING_VIOLATIONS = %w[.git .atom .].freeze
# The first date in https://docs.gitlab.com/ee/user/usage_quotas.html#namespace-storage-limit-enforcement-schedule
# Determines when we start enforcing namespace storage
MIN_STORAGE_ENFORCEMENT_DATE = Date.new(2022, 10, 19)
cache_markdown_field :description, pipeline: :description
has_many :projects, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
@ -560,9 +564,7 @@ class Namespace < ApplicationRecord
def storage_enforcement_date
return Date.current if Feature.enabled?(:namespace_storage_limit_bypass_date_check, self)
# should return something like Date.new(2022, 02, 03)
# TBD: https://gitlab.com/gitlab-org/gitlab/-/issues/350632
nil
MIN_STORAGE_ENFORCEMENT_DATE
end
def certificate_based_clusters_enabled?

View File

@ -6,7 +6,7 @@
- @left_sidebar = true
- content_for :flash_message do
= render "layouts/header/storage_enforcement_banner", namespace: @group
= render "layouts/header/storage_enforcement_banner", context: @group
= dispensable_render_if_exists "shared/namespace_storage_limit_alert"
- content_for :page_specific_javascripts do

View File

@ -1,14 +1,15 @@
- return unless current_user
- namespace = local_assigns.fetch(:namespace)
- banner_info = storage_enforcement_banner_info(namespace)
- context = local_assigns.fetch(:context)
- banner_info = storage_enforcement_banner_info(context)
- return unless banner_info.present?
= render Pajamas::AlertComponent.new(variant: :warning,
alert_options: { class: 'js-storage-enforcement-banner',
data: { feature_id: banner_info[:callouts_feature_name],
dismiss_endpoint: banner_info[:callouts_path],
group_id: namespace.id,
group_id: banner_info[:namespace_id],
defer_links: "true" }}) do |c|
= c.body do
= banner_info[:text]
= banner_info[:learn_more_link]
%p= banner_info[:text_paragraph_1]
%p= banner_info[:text_paragraph_2]
%p= banner_info[:text_paragraph_3]

View File

@ -7,6 +7,6 @@
- enable_search_settings locals: { container_class: 'gl-my-5' }
- content_for :flash_message do
= render "layouts/header/storage_enforcement_banner", namespace: current_user.namespace
= render "layouts/header/storage_enforcement_banner", context: current_user.namespace
= render template: "layouts/application"

View File

@ -8,7 +8,7 @@
- @content_class = [@content_class, project_classes(@project)].compact.join(" ")
- content_for :flash_message do
= render "layouts/header/storage_enforcement_banner", namespace: @project.namespace
= render "layouts/header/storage_enforcement_banner", context: @project
= dispensable_render_if_exists "shared/namespace_storage_limit_alert"
- content_for :project_javascripts do

View File

@ -536,6 +536,7 @@ module Gitlab
config.after_initialize do
config.active_record.yaml_column_permitted_classes = [
Symbol, Date, Time,
BigDecimal, # https://gitlab.com/gitlab-org/gitlab/issues/368846
Gitlab::Diff::Position,
# Used in:
# app/models/concerns/diff_positionable_note.rb
@ -546,7 +547,8 @@ module Gitlab
ActiveModel::Attribute.const_get(:FromDatabase, false), # https://gitlab.com/gitlab-org/gitlab/-/issues/368072
# Used in app/services/web_hooks/log_execution_service.rb: log_execution
ActiveSupport::TimeWithZone,
ActiveSupport::TimeZone
ActiveSupport::TimeZone,
Gitlab::Color # https://gitlab.com/gitlab-org/gitlab/-/issues/368844
]
# on_master_start yields immediately in unclustered environments and runs

View File

@ -1,8 +0,0 @@
---
name: ci_fix_rules_if_comparison_with_regexp_variable
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/85310
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/359740
milestone: '15.0'
type: development
group: group::pipeline authoring
default_enabled: true

View File

@ -555,6 +555,11 @@ module.exports = {
);
}),
new webpack.NormalModuleReplacementPlugin(/markdown-it/, (resource) => {
// eslint-disable-next-line no-param-reassign
resource.request = path.join(ROOT_PATH, 'app/assets/javascripts/lib/markdown_it.js');
}),
!IS_JH &&
new webpack.NormalModuleReplacementPlugin(/^jh_component\/(.*)\.vue/, (resource) => {
// eslint-disable-next-line no-param-reassign

View File

@ -1,77 +1,11 @@
# frozen_string_literal: true
class AssociateExistingDastBuildsWithVariables < ActiveRecord::Migration[6.1]
disable_ddl_transaction!
class Profile < ApplicationRecord
self.table_name = 'dast_profiles'
self.inheritance_column = :_type_disabled
end
class ProfilesPipeline < ApplicationRecord
include EachBatch
self.table_name = 'dast_profiles_pipelines'
self.inheritance_column = :_type_disabled
belongs_to :profile, foreign_key: :dast_profile_id
end
class Build < ApplicationRecord
self.table_name = 'ci_builds'
self.inheritance_column = :_type_disabled
default_scope { where(name: :dast, stage: :dast) } # rubocop:disable Cop/DefaultScope
end
class SiteProfilesBuild < ApplicationRecord
self.table_name = 'dast_site_profiles_builds'
self.inheritance_column = :_type_disabled
end
BATCH_SIZE = 300
def up
process_batch do |batch|
bulk_inserts = []
grouped_builds = fetch_builds(batch).group_by(&:commit_id)
batch.includes(:profile).each do |profile_pipeline|
builds = grouped_builds[profile_pipeline.ci_pipeline_id]
next if builds.blank?
builds.each do |build|
bulk_inserts.push(dast_site_profile_id: profile_pipeline.profile.dast_site_profile_id, ci_build_id: build.id)
end
end
SiteProfilesBuild.insert_all(bulk_inserts, unique_by: :ci_build_id)
end
# no-op: Must have run before %"15.X" as it is not compatible with decomposed CI database
end
def down
process_batch do |batch|
builds = fetch_builds(batch)
SiteProfilesBuild
.where(ci_build_id: builds)
.delete_all
end
end
private
def fetch_builds(batch)
# pluck necessary to support ci table decomposition
# https://gitlab.com/groups/gitlab-org/-/epics/6289
Build.where(commit_id: batch.pluck(:ci_pipeline_id))
end
def process_batch
ProfilesPipeline.each_batch(of: BATCH_SIZE, column: :ci_pipeline_id) do |batch|
yield(batch)
end
# No-op
end
end

View File

@ -1,32 +1,8 @@
# frozen_string_literal: true
class ScheduleCopyCiBuildsColumnsToSecurityScans2 < ActiveRecord::Migration[6.1]
include Gitlab::Database::MigrationHelpers
INTERVAL = 2.minutes.to_i
BATCH_SIZE = 5_000
MIGRATION = 'CopyCiBuildsColumnsToSecurityScans'
disable_ddl_transaction!
class SecurityScan < ActiveRecord::Base
include EachBatch
self.table_name = 'security_scans'
end
def up
SecurityScan.reset_column_information
delete_job_tracking(MIGRATION, status: %w[pending succeeded])
queue_background_migration_jobs_by_range_at_intervals(
SecurityScan,
MIGRATION,
INTERVAL,
batch_size: BATCH_SIZE,
track_jobs: true
)
# no-op: Must have run before %"15.X" as it is not compatible with decomposed CI database
end
def down

View File

@ -1,52 +1,11 @@
# frozen_string_literal: true
class DisableJobTokenScopeWhenUnused < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
class ProjectCiCdSetting < ApplicationRecord
include EachBatch
self.table_name = 'project_ci_cd_settings'
end
module Ci
module JobToken
class ProjectScopeLink < ApplicationRecord
self.table_name = 'ci_job_token_project_scope_links'
end
end
end
def up
# Disabling job token scope after db/migrate/20210902171808_set_default_job_token_scope_false.rb
# if users haven't configured it.
ProjectCiCdSetting.each_batch(of: 10_000) do |settings|
with_enabled_but_unused_scope(settings).each_batch(of: 500) do |settings_to_update|
settings_to_update.update_all(job_token_scope_enabled: false)
end
end
# no-op: Must have run before %"15.X" as it is not compatible with decomposed CI database
end
def down
# irreversible data migration
# The migration relies on the state of `job_token_scope_enabled` and
# updates it based on whether the feature is used or not.
#
# The inverse migration would be to set `job_token_scope_enabled: true`
# for those projects that have the feature disabled and unused. But there
# could be also existing cases where the feature is disabled and unused.
# For example, old projects.
end
private
# The presence of ProjectScopeLinks means that the job token scope
# is configured and we need to leave it enabled. Unused job token scope
# can be disabled since they weren't configured.
def with_enabled_but_unused_scope(settings)
settings
.where(job_token_scope_enabled: true)
.where.not(project_id: Ci::JobToken::ProjectScopeLink.select(:source_project_id))
# no-op
end
end

View File

@ -0,0 +1,23 @@
# frozen_string_literal: true
class ScheduleBackfillingTheNamespaceIdForVulnerabilityReads < Gitlab::Database::Migration[2.0]
MIGRATION_NAME = 'BackfillNamespaceIdOfVulnerabilityReads'
restrict_gitlab_migration gitlab_schema: :gitlab_main
disable_ddl_transaction!
def up
queue_batched_background_migration(
MIGRATION_NAME,
:vulnerability_reads,
:vulnerability_id,
job_interval: 2.minutes,
batch_size: 10_000,
sub_batch_size: 200
)
end
def down
delete_batched_background_migration(MIGRATION_NAME, :vulnerability_reads, :vulnerability_id, [])
end
end

View File

@ -0,0 +1 @@
612a9cf3004e4d837749ef522ed72920275c9ddd8570b1a5a5e6ff51b49afd67

View File

@ -1,23 +1,19 @@
---
# Error: gitlab.VersionText
#
# Checks that version text is formatted correctly.
# Checks that multi-line version text is formatted correctly.
#
# Specifically looks for either of the following that is immediately followed on the next line
# by content, which will break rendering:
# Specifically, looks for multi-line version text that doesn't use `-` to make it a list.
# For example:
#
# - `> Introduced` (version text without a link)
# - `> [Introduced` (version text with a link)
#
# Because it excludes the prefix `> - `, it doesn't look for multi-line version text, for which
# content immediately on the next line is ok. However, this will often highlight where multi-line
# version text is attempted without `-` characters.
# - `> Introduced in GitLab 14.0.
# - `> Removed in GitLab 15.0.
#
# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
extends: existence
message: 'This introduced-in line is not formatted correctly.'
message: 'This introduced-in section is not formatted correctly. Each entry must start with `> -` and long entries must be on one line.'
link: https://docs.gitlab.com/ee/development/documentation/versions.html
level: error
scope: raw
raw:
- '> \[?Introduced.+\n[^\n]'
- '\n#.*\n\n> [^-].+\n[^\n`]'

View File

@ -18,8 +18,8 @@ After completing the integration, Mailgun `temporary_failure` and `permanent_fai
## Configure your Mailgun domain
> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/359113) the `/-/members/mailgun/permanent_failures` URL in GitLab 15.0.
> [Added](https://gitlab.com/gitlab-org/gitlab/-/issues/359113) the URL to handle both temporary and permanent failures in GitLab 15.0.
> - [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/359113) the `/-/members/mailgun/permanent_failures` URL in GitLab 15.0.
> - [Added](https://gitlab.com/gitlab-org/gitlab/-/issues/359113) the URL to handle both temporary and permanent failures in GitLab 15.0.
Before you can enable Mailgun in GitLab, set up your own Mailgun endpoints to receive the webhooks.

View File

@ -8,8 +8,7 @@ redirect_to: 'index.md'
# Pseudonymizer (removed) **(ULTIMATE)**
> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/219952) in
> GitLab 14.7 and removed in 15.0.
> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/219952) in GitLab 14.7 and removed in 15.0.
WARNING:
This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/219952) in GitLab 14.7.

View File

@ -29,9 +29,9 @@ When requested across groups or projects, it's expected to be the same as the `f
## List issues
> The `due_date` property was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/233420) in GitLab 13.3.
> The `weight` property moved to GitLab Premium in 13.9.
> The `due_date` filters `any`, `today`, and `tomorrow` were [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78460) in GitLab 14.8.
> - The `due_date` property was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/233420) in GitLab 13.3.
> - The `weight` property moved to GitLab Premium in 13.9.
> - The `due_date` filters `any`, `today`, and `tomorrow` were [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78460) in GitLab 14.8.
Get all issues the authenticated user has access to. By default it
returns only issues created by the current user. To get all issues,
@ -257,9 +257,9 @@ Please use `iid` of the `epic` attribute instead.
## List group issues
> The `due_date` property was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/233420) in GitLab 13.3.
> The `weight` property moved to GitLab Premium in 13.9.
> The `due_date` filters `any`, `today`, and `tomorrow` were [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78460) in GitLab 14.8.
> - The `due_date` property was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/233420) in GitLab 13.3.
> - The `weight` property moved to GitLab Premium in 13.9.
> - The `due_date` filters `any`, `today`, and `tomorrow` were [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78460) in GitLab 14.8.
Get a list of a group's issues.
@ -461,9 +461,9 @@ Please use `iid` of the `epic` attribute instead.
## List project issues
> The `due_date` property was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/233420) in GitLab 13.3.
> The `weight` property moved to GitLab Premium in 13.9.
> The `due_date` filters `any`, `today`, and `tomorrow` were [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78460) in GitLab 14.8.
> - The `due_date` property was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/233420) in GitLab 13.3.
> - The `weight` property moved to GitLab Premium in 13.9.
> - The `due_date` filters `any`, `today`, and `tomorrow` were [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78460) in GitLab 14.8.
Get a list of a project's issues.

View File

@ -125,8 +125,8 @@ Supported attributes:
## Get file archive
> Support for [including Git LFS blobs](../topics/git/lfs/index.md#lfs-objects-in-project-archives) was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15079) in GitLab 13.5.
> Support for downloading a subfolder was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/28827) in GitLab 14.4.
> - Support for [including Git LFS blobs](../topics/git/lfs/index.md#lfs-objects-in-project-archives) was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15079) in GitLab 13.5.
> - Support for downloading a subfolder was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/28827) in GitLab 14.4.
Get an archive of the repository. This endpoint can be accessed without
authentication if the repository is publicly accessible.

View File

@ -250,8 +250,8 @@ using the [`coverage`](../yaml/index.md#coverage) keyword.
### Add test coverage results using project settings (removed)
> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/17633) in GitLab 14.8. Replaced by [`coverage` keyword](../yaml/index.md#coverage).
> [Removed](https://gitlab.com/gitlab-org/gitlab/-/issues/17633) in GitLab 15.0.
> - [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/17633) in GitLab 14.8. Replaced by [`coverage` keyword](../yaml/index.md#coverage).
> - [Removed](https://gitlab.com/gitlab-org/gitlab/-/issues/17633) in GitLab 15.0.
This feature is in its end-of-life process. It was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/17633)
in GitLab 14.8. The feature is [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/17633) in GitLab 15.0.

View File

@ -59,7 +59,7 @@ end
## Declared parameters
> Grape allows you to access only the parameters that have been declared by your
Grape allows you to access only the parameters that have been declared by your
`params` block. It filters out the parameters that have been passed, but are not
allowed.
@ -67,7 +67,7 @@ allowed.
### Exclude parameters from parent namespaces
> By default `declared(params)`includes parameters that were defined in all
By default `declared(params)`includes parameters that were defined in all
parent namespaces.
<https://github.com/ruby-grape/grape#include-parent-namespaces>

View File

@ -44,6 +44,7 @@ We have built a domain-specific language (DSL) to define the metrics instrumenta
- `finish`: Specifies the end value of the batch counting, by default is `relation.maximum(:id)`.
- `cache_start_and_finish_as`: Specifies the cache key for `start` and `finish` values and sets up caching them. Use this call when `start` and `finish` are expensive queries that should be reused between different metric calculations.
- `available?`: Specifies whether the metric should be reported. The default is `true`.
- `timestamp_column`: Optionally specifies timestamp column for metric used to filter records for time constrained metrics. The default is `created_at`.
[Example of a merge request that adds a database metric](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60022).

View File

@ -7,9 +7,9 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Notification emails **(FREE)**
> Enhanced email styling [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78604) in GitLab 14.9 [with a feature flag](../../administration/feature_flags.md) named `enhanced_notify_css`. Disabled by default.
> Enhanced email styling [enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/355907) in GitLab 14.9.
> Enhanced email styling [enabled on self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/355907) in GitLab 15.0.
> - Enhanced email styling [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78604) in GitLab 14.9 [with a feature flag](../../administration/feature_flags.md) named `enhanced_notify_css`. Disabled by default.
> - Enhanced email styling [enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/355907) in GitLab 14.9.
> - Enhanced email styling [enabled on self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/355907) in GitLab 15.0.
Stay informed about what's happening in GitLab with email notifications.
You can receive updates about activity in issues, merge requests, epics, and designs.

View File

@ -123,8 +123,8 @@ example, if the list is scoped to a label `Frontend`, the new issue also has thi
### By sending an email
> Generated email address format changed in GitLab 11.7.
> The older format is still supported, so existing aliases and contacts still work.
> - Generated email address format changed in GitLab 11.7.
> - The older format is still supported, so existing aliases and contacts still work.
You can send an email to create an issue in a project on the project's
**Issues List** page.

View File

@ -307,8 +307,7 @@ In these issues, you can also see our friendly neighborhood [Support Bot](#suppo
### As an end user (issue creator)
> Support for additional email headers [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/346600) in GitLab 14.6.
> In earlier versions, the Service Desk email address had to be in the "To" field.
> Support for additional email headers [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/346600) in GitLab 14.6. In earlier versions, the Service Desk email address had to be in the "To" field.
To create a Service Desk issue, an end user does not need to know anything about
the GitLab instance. They just send an email to the address they are given, and

View File

@ -0,0 +1,36 @@
# frozen_string_literal: true
module Gitlab
module BackgroundMigration
# Sets the `namespace_id` of the existing `vulnerability_reads` records
class BackfillNamespaceIdOfVulnerabilityReads < BatchedMigrationJob
UPDATE_SQL = <<~SQL
UPDATE
vulnerability_reads
SET
namespace_id = sub_query.namespace_id
FROM
(%<subquery>s) as sub_query
WHERE
vulnerability_reads.vulnerability_id = sub_query.vulnerability_id
SQL
def perform
each_sub_batch(operation_name: :set_namespace_id) do |sub_batch|
update_query = update_query_for(sub_batch)
connection.execute(update_query)
end
end
private
def update_query_for(sub_batch)
subquery = sub_batch.select("vulnerability_reads.vulnerability_id, projects.namespace_id")
.joins("INNER JOIN projects ON projects.id = vulnerability_reads.project_id")
format(UPDATE_SQL, subquery: subquery.to_sql)
end
end
end
end

View File

@ -1,44 +0,0 @@
# frozen_string_literal: true
# rubocop:disable Style/Documentation
module Gitlab
module BackgroundMigration
class CopyCiBuildsColumnsToSecurityScans
extend ::Gitlab::Utils::Override
UPDATE_BATCH_SIZE = 500
def perform(start_id, stop_id)
(start_id..stop_id).step(UPDATE_BATCH_SIZE).each do |offset|
batch_start = offset
batch_stop = offset + UPDATE_BATCH_SIZE - 1
ActiveRecord::Base.connection.execute <<~SQL
UPDATE
security_scans
SET
project_id = ci_builds.project_id,
pipeline_id = ci_builds.commit_id
FROM ci_builds
WHERE ci_builds.type='Ci::Build'
AND ci_builds.id=security_scans.build_id
AND security_scans.id BETWEEN #{Integer(batch_start)} AND #{Integer(batch_stop)}
SQL
end
mark_job_as_succeeded(start_id, stop_id)
rescue StandardError => error
Gitlab::ErrorTracking.track_and_raise_for_dev_exception(error)
end
private
def mark_job_as_succeeded(*arguments)
Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded(
'CopyCiBuildsColumnsToSecurityScans',
arguments
)
end
end
end
end

View File

@ -14,11 +14,9 @@ module Gitlab
return false unless regexp
if ::Feature.enabled?(:ci_fix_rules_if_comparison_with_regexp_variable)
# All variables are evaluated as strings, even if they are regexp strings.
# So, we need to convert them to regexp objects.
regexp = Lexeme::Pattern.build_and_evaluate(regexp, variables)
end
# All variables are evaluated as strings, even if they are regexp strings.
# So, we need to convert them to regexp objects.
regexp = Lexeme::Pattern.build_and_evaluate(regexp, variables)
regexp.scan(text.to_s).present?
end

View File

@ -14,11 +14,9 @@ module Gitlab
return true unless regexp
if ::Feature.enabled?(:ci_fix_rules_if_comparison_with_regexp_variable)
# All variables are evaluated as strings, even if they are regexp strings.
# So, we need to convert them to regexp objects.
regexp = Lexeme::Pattern.build_and_evaluate(regexp, variables)
end
# All variables are evaluated as strings, even if they are regexp strings.
# So, we need to convert them to regexp objects.
regexp = Lexeme::Pattern.build_and_evaluate(regexp, variables)
regexp.scan(text.to_s).empty?
end

View File

@ -52,6 +52,10 @@ module Gitlab
def self.doc_url
'https://docs.gitlab.com'
end
def self.community_forum_url
'https://forum.gitlab.com'
end
end
end

View File

@ -46,6 +46,10 @@ module Gitlab
@metric_options = block
end
def timestamp_column(symbol)
@metric_timestamp_column = symbol
end
def operation(symbol, column: nil, &block)
raise UnimplementedOperationError unless symbol.in?(IMPLEMENTED_OPERATIONS)
@ -58,7 +62,9 @@ module Gitlab
@cache_key = cache_key
end
attr_reader :metric_operation, :metric_relation, :metric_start, :metric_finish, :metric_operation_block, :column, :cache_key
attr_reader :metric_operation, :metric_relation, :metric_start,
:metric_finish, :metric_operation_block,
:column, :cache_key, :metric_timestamp_column
end
def value
@ -106,7 +112,7 @@ module Gitlab
def time_constraints
case time_frame
when '28d'
monthly_time_range_db_params
monthly_time_range_db_params(column: self.class.metric_timestamp_column)
when 'all'
{}
when 'none'

View File

@ -6,6 +6,7 @@ module Gitlab
ALL_TIME_TIME_FRAME_NAME = "all"
SEVEN_DAYS_TIME_FRAME_NAME = "7d"
TWENTY_EIGHT_DAYS_TIME_FRAME_NAME = "28d"
DEFAULT_TIMESTAMP_COLUMN = :created_at
def weekly_time_range
{ start_date: 7.days.ago.to_date, end_date: Date.current }
@ -17,8 +18,8 @@ module Gitlab
# This time range is skewed for batch counter performance.
# See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/42972
def monthly_time_range_db_params(column: :created_at)
{ column => 30.days.ago..2.days.ago }
def monthly_time_range_db_params(column: nil)
{ (column || DEFAULT_TIMESTAMP_COLUMN) => 30.days.ago..2.days.ago }
end
end
end

View File

@ -4055,9 +4055,6 @@ msgstr ""
msgid "An error occurred while fetching ancestors"
msgstr ""
msgid "An error occurred while fetching branches."
msgstr ""
msgid "An error occurred while fetching branches. Retry the search."
msgstr ""
@ -6630,6 +6627,42 @@ msgstr ""
msgid "Branch rules"
msgstr ""
msgid "BranchRules|%{linkStart}Wildcards%{linkEnd} such as *-stable or production/* are supported."
msgstr ""
msgid "BranchRules|Allow all users with push access to %{linkStart}force push%{linkEnd}."
msgstr ""
msgid "BranchRules|Allowed to merge"
msgstr ""
msgid "BranchRules|Allowed to push"
msgstr ""
msgid "BranchRules|An error occurred while fetching branches."
msgstr ""
msgid "BranchRules|Branch"
msgstr ""
msgid "BranchRules|Create wildcard: %{searchTerm}"
msgstr ""
msgid "BranchRules|Keep stable branches secure and force developers to use merge requests. %{linkStart}What are protected branches?%{linkEnd}"
msgstr ""
msgid "BranchRules|No matching results"
msgstr ""
msgid "BranchRules|Protections"
msgstr ""
msgid "BranchRules|Reject code pushes that change files listed in the CODEOWNERS file."
msgstr ""
msgid "BranchRules|Require approval from code owners."
msgstr ""
msgid "Branches"
msgstr ""
@ -41733,10 +41766,10 @@ msgstr ""
msgid "UsageQuota|Dependency proxy"
msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgid "UsageQuota|Effective %{storage_enforcement_date}, %{announcement_link_start}namespace storage limits will apply%{link_end} to the %{strong_start}%{namespace_name}%{strong_end} namespace. %{extra_message}View the %{rollout_link_start}rollout schedule for this change%{link_end}."
msgstr ""
msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. You are currently using %{used_storage} of namespace storage. View and manage your usage from %{strong_start}%{namespace_type} settings &gt; Usage quotas%{strong_end}."
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
msgid "UsageQuota|Git repository."
@ -41808,6 +41841,9 @@ msgstr ""
msgid "UsageQuota|Seats"
msgstr ""
msgid "UsageQuota|See our %{faq_link_start}FAQ%{link_end} for more information."
msgstr ""
msgid "UsageQuota|Shared bits of code and text."
msgstr ""
@ -41835,6 +41871,18 @@ msgstr ""
msgid "UsageQuota|Storage used"
msgstr ""
msgid "UsageQuota|The %{strong_start}%{context_name}%{strong_end} group will be affected by this. "
msgstr ""
msgid "UsageQuota|The %{strong_start}%{context_name}%{strong_end} project will be affected by this. "
msgstr ""
msgid "UsageQuota|The namespace is currently using %{strong_start}%{used_storage}%{strong_end} of namespace storage. View and manage your usage from %{strong_start}Group settings &gt; Usage quotas%{strong_end}. %{docs_link_start}Learn more%{link_end} about how to reduce your storage."
msgstr ""
msgid "UsageQuota|The namespace is currently using %{strong_start}%{used_storage}%{strong_end} of namespace storage. View and manage your usage from %{strong_start}User settings &gt; Usage quotas%{strong_end}. %{docs_link_start}Learn more%{link_end} about how to reduce your storage."
msgstr ""
msgid "UsageQuota|The table below shows current period usage"
msgstr ""

View File

@ -46,6 +46,7 @@
"webpack-prod": "NODE_OPTIONS=\"--max-old-space-size=3584\" NODE_ENV=production webpack --config config/webpack.config.js"
},
"dependencies": {
"@_ueberdosis/prosemirror-tables": "^1.1.3",
"@apollo/client": "^3.5.10",
"@babel/core": "^7.18.5",
"@babel/preset-env": "^7.18.2",
@ -58,36 +59,36 @@
"@rails/ujs": "6.1.4-7",
"@sentry/browser": "5.30.0",
"@sourcegraph/code-host-integration": "0.0.60",
"@tiptap/core": "^2.0.0-beta.176",
"@tiptap/extension-blockquote": "^2.0.0-beta.26",
"@tiptap/extension-bold": "^2.0.0-beta.26",
"@tiptap/extension-bullet-list": "^2.0.0-beta.26",
"@tiptap/extension-code": "^2.0.0-beta.26",
"@tiptap/extension-code-block-lowlight": "2.0.0-beta.68",
"@tiptap/extension-document": "^2.0.0-beta.15",
"@tiptap/extension-dropcursor": "^2.0.0-beta.25",
"@tiptap/extension-gapcursor": "^2.0.0-beta.34",
"@tiptap/extension-hard-break": "^2.0.0-beta.30",
"@tiptap/extension-heading": "^2.0.0-beta.26",
"@tiptap/extension-history": "^2.0.0-beta.21",
"@tiptap/extension-horizontal-rule": "^2.0.0-beta.31",
"@tiptap/extension-image": "^2.0.0-beta.27",
"@tiptap/extension-italic": "^2.0.0-beta.26",
"@tiptap/extension-link": "^2.0.0-beta.38",
"@tiptap/extension-list-item": "^2.0.0-beta.20",
"@tiptap/extension-ordered-list": "^2.0.0-beta.27",
"@tiptap/extension-paragraph": "^2.0.0-beta.23",
"@tiptap/extension-strike": "^2.0.0-beta.27",
"@tiptap/extension-subscript": "^2.0.0-beta.10",
"@tiptap/extension-superscript": "^2.0.0-beta.10",
"@tiptap/extension-table": "^2.0.0-beta.49",
"@tiptap/extension-table-cell": "^2.0.0-beta.20",
"@tiptap/extension-table-header": "^2.0.0-beta.22",
"@tiptap/extension-table-row": "^2.0.0-beta.19",
"@tiptap/extension-task-item": "^2.0.0-beta.32",
"@tiptap/extension-task-list": "^2.0.0-beta.26",
"@tiptap/extension-text": "^2.0.0-beta.15",
"@tiptap/vue-2": "^2.0.0-beta.79",
"@tiptap/core": "^2.0.0-beta.182",
"@tiptap/extension-blockquote": "^2.0.0-beta.29",
"@tiptap/extension-bold": "^2.0.0-beta.28",
"@tiptap/extension-bullet-list": "^2.0.0-beta.29",
"@tiptap/extension-code": "^2.0.0-beta.28",
"@tiptap/extension-code-block-lowlight": "2.0.0-beta.73",
"@tiptap/extension-document": "^2.0.0-beta.17",
"@tiptap/extension-dropcursor": "^2.0.0-beta.28",
"@tiptap/extension-gapcursor": "^2.0.0-beta.38",
"@tiptap/extension-hard-break": "^2.0.0-beta.33",
"@tiptap/extension-heading": "^2.0.0-beta.29",
"@tiptap/extension-history": "^2.0.0-beta.25",
"@tiptap/extension-horizontal-rule": "^2.0.0-beta.36",
"@tiptap/extension-image": "^2.0.0-beta.30",
"@tiptap/extension-italic": "^2.0.0-beta.28",
"@tiptap/extension-link": "^2.0.0-beta.43",
"@tiptap/extension-list-item": "^2.0.0-beta.23",
"@tiptap/extension-ordered-list": "^2.0.0-beta.30",
"@tiptap/extension-paragraph": "^2.0.0-beta.26",
"@tiptap/extension-strike": "^2.0.0-beta.29",
"@tiptap/extension-subscript": "^2.0.0-beta.13",
"@tiptap/extension-superscript": "^2.0.0-beta.13",
"@tiptap/extension-table": "^2.0.0-beta.54",
"@tiptap/extension-table-cell": "^2.0.0-beta.23",
"@tiptap/extension-table-header": "^2.0.0-beta.25",
"@tiptap/extension-table-row": "^2.0.0-beta.22",
"@tiptap/extension-task-item": "^2.0.0-beta.37",
"@tiptap/extension-task-list": "^2.0.0-beta.29",
"@tiptap/extension-text": "^2.0.0-beta.17",
"@tiptap/vue-2": "^2.0.0-beta.84",
"apollo-upload-client": "15.0.0",
"autosize": "^5.0.1",
"aws-sdk": "^2.637.0",
@ -152,11 +153,10 @@
"portal-vue": "^2.1.7",
"postcss": "8.4.14",
"prismjs": "^1.21.0",
"prosemirror-markdown": "1.8.0",
"prosemirror-model": "^1.16.1",
"prosemirror-state": "^1.3.4",
"prosemirror-tables": "^1.1.1",
"prosemirror-view": "^1.23.13",
"prosemirror-markdown": "1.9.1",
"prosemirror-model": "^1.18.1",
"prosemirror-state": "^1.4.1",
"prosemirror-view": "^1.26.1",
"raphael": "^2.2.7",
"raw-loader": "^4.0.2",
"rehype-raw": "^6.1.1",
@ -241,9 +241,9 @@
"mock-apollo-client": "1.2.0",
"nodemon": "^2.0.19",
"prettier": "2.2.1",
"prosemirror-schema-basic": "^1.1.2",
"prosemirror-schema-list": "^1.1.6",
"prosemirror-test-builder": "^1.0.6",
"prosemirror-schema-basic": "^1.2.0",
"prosemirror-schema-list": "^1.2.0",
"prosemirror-test-builder": "^1.1.0",
"purgecss": "^4.0.3",
"purgecss-from-html": "^4.0.3",
"sass": "^1.49.9",

View File

@ -135,6 +135,7 @@ RSpec.describe 'Project issue boards', :js do
find('.board .board-list')
inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do
evaluate_script("window.scrollTo(0, document.body.scrollHeight)")
evaluate_script("document.querySelectorAll('.board .board-list')[1].scrollTop = document.querySelectorAll('.board .board-list')[1].scrollHeight")
end
@ -144,6 +145,7 @@ RSpec.describe 'Project issue boards', :js do
find('.board .board-list')
inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do
evaluate_script("window.scrollTo(0, document.body.scrollHeight)")
evaluate_script("document.querySelectorAll('.board .board-list')[1].scrollTop = document.querySelectorAll('.board .board-list')[1].scrollHeight")
end
@ -153,6 +155,7 @@ RSpec.describe 'Project issue boards', :js do
find('.board .board-list')
inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do
evaluate_script("window.scrollTo(0, document.body.scrollHeight)")
evaluate_script("document.querySelectorAll('.board .board-list')[1].scrollTop = document.querySelectorAll('.board .board-list')[1].scrollHeight")
end
@ -400,6 +403,7 @@ RSpec.describe 'Project issue boards', :js do
find('.board .board-list')
inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do
evaluate_script("window.scrollTo(0, document.body.scrollHeight)")
evaluate_script("document.querySelectorAll('.board .board-list')[1].scrollTop = document.querySelectorAll('.board .board-list')[1].scrollHeight")
end
@ -409,6 +413,7 @@ RSpec.describe 'Project issue boards', :js do
find('.board .board-list')
inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do
evaluate_script("window.scrollTo(0, document.body.scrollHeight)")
evaluate_script("document.querySelectorAll('.board .board-list')[1].scrollTop = document.querySelectorAll('.board .board-list')[1].scrollHeight")
end
@ -417,6 +422,7 @@ RSpec.describe 'Project issue boards', :js do
find('.board .board-list')
inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do
evaluate_script("window.scrollTo(0, document.body.scrollHeight)")
evaluate_script("document.querySelectorAll('.board .board-list')[1].scrollTop = document.querySelectorAll('.board .board-list')[1].scrollHeight")
end

View File

@ -531,8 +531,8 @@ RSpec.describe 'Group' do
let_it_be(:storage_enforcement_date) { Date.today + 30 }
before do
allow_next_found_instance_of(Group) do |grp|
allow(grp).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
allow_next_found_instance_of(Group) do |group|
allow(group).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
end
end
@ -542,8 +542,8 @@ RSpec.describe 'Group' do
end
it 'does not display the banner in a paid group page' do
allow_next_found_instance_of(Group) do |grp|
allow(grp).to receive(:paid?).and_return(true)
allow_next_found_instance_of(Group) do |group|
allow(group).to receive(:paid?).and_return(true)
end
visit group_path(group)
expect_page_not_to_have_storage_enforcement_banner
@ -558,8 +558,8 @@ RSpec.describe 'Group' do
expect_page_not_to_have_storage_enforcement_banner
storage_enforcement_date = Date.today + 13
allow_next_found_instance_of(Group) do |grp|
allow(grp).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
allow_next_found_instance_of(Group) do |group|
allow(group).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
end
page.refresh
expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
@ -567,8 +567,12 @@ RSpec.describe 'Group' do
end
context 'with storage_enforcement_date not set' do
# This test should break and be rewritten after the implementation of the storage_enforcement_date
# TBD: https://gitlab.com/gitlab-org/gitlab/-/issues/350632
before do
allow_next_found_instance_of(Group) do |group|
allow(group).to receive(:storage_enforcement_date).and_return(nil)
end
end
it 'does not display the banner in the group page' do
stub_feature_flags(namespace_storage_limit_bypass_date_check: false)
visit group_path(group)
@ -578,10 +582,10 @@ RSpec.describe 'Group' do
end
def expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
expect(page).to have_text "From #{storage_enforcement_date} storage limits will apply to this namespace"
expect(page).to have_text "Effective #{storage_enforcement_date}, namespace storage limits will apply"
end
def expect_page_not_to_have_storage_enforcement_banner
expect(page).not_to have_text "storage limits will apply to this namespace"
expect(page).not_to have_text "namespace storage limits will apply"
end
end

View File

@ -97,8 +97,8 @@ RSpec.describe 'User visits their profile' do
let_it_be(:storage_enforcement_date) { Date.today + 30 }
before do
allow_next_found_instance_of(Namespaces::UserNamespace) do |g|
allow(g).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
allow_next_found_instance_of(Namespaces::UserNamespace) do |user_namespace|
allow(user_namespace).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
end
end
@ -115,8 +115,8 @@ RSpec.describe 'User visits their profile' do
expect_page_not_to_have_storage_enforcement_banner
storage_enforcement_date = Date.today + 13
allow_next_found_instance_of(Namespaces::UserNamespace) do |g|
allow(g).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
allow_next_found_instance_of(Namespaces::UserNamespace) do |user_namespace|
allow(user_namespace).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
end
page.refresh
expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
@ -124,8 +124,12 @@ RSpec.describe 'User visits their profile' do
end
context 'with storage_enforcement_date not set' do
# This test should break and be rewritten after the implementation of the storage_enforcement_date
# TBD: https://gitlab.com/gitlab-org/gitlab/-/issues/350632
before do
allow_next_found_instance_of(Namespaces::UserNamespace) do |user_namespace|
allow(user_namespace).to receive(:storage_enforcement_date).and_return(nil)
end
end
it 'does not display the banner in the group page' do
visit(profile_path)
expect_page_not_to_have_storage_enforcement_banner
@ -134,10 +138,10 @@ RSpec.describe 'User visits their profile' do
end
def expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
expect(page).to have_text "From #{storage_enforcement_date} storage limits will apply to this namespace"
expect(page).to have_text "Effective #{storage_enforcement_date}, namespace storage limits will apply"
end
def expect_page_not_to_have_storage_enforcement_banner
expect(page).not_to have_text "storage limits will apply to this namespace"
expect(page).not_to have_text "namespace storage limits will apply"
end
end

View File

@ -113,7 +113,7 @@ RSpec.describe "Compare", :js do
click_button('Compare')
page.within('.gl-alert') do
page.within('[data-testid="too-many-changes-alert"]') do
expect(page).to have_text("Too many changes to show. To preserve performance only 3 of 3+ files are displayed.")
end
end

View File

@ -454,8 +454,8 @@ RSpec.describe 'Project' do
let_it_be(:storage_enforcement_date) { Date.today + 30 }
before do
allow_next_found_instance_of(Group) do |grp|
allow(grp).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
allow_next_found_instance_of(Group) do |group|
allow(group).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
end
end
@ -478,8 +478,8 @@ RSpec.describe 'Project' do
let_it_be(:project) { create(:project, namespace: user.namespace) }
before do
allow_next_found_instance_of(Namespaces::UserNamespace) do |namspace|
allow(namspace).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
allow_next_found_instance_of(Namespaces::UserNamespace) do |user_namespace|
allow(user_namespace).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
end
end
@ -490,8 +490,8 @@ RSpec.describe 'Project' do
end
it 'does not display the banner in a paid group project page' do
allow_next_found_instance_of(Group) do |grp|
allow(grp).to receive(:paid?).and_return(true)
allow_next_found_instance_of(Group) do |group|
allow(group).to receive(:paid?).and_return(true)
end
visit project_path(project)
expect_page_not_to_have_storage_enforcement_banner
@ -506,8 +506,8 @@ RSpec.describe 'Project' do
expect_page_not_to_have_storage_enforcement_banner
storage_enforcement_date = Date.today + 13
allow_next_found_instance_of(Group) do |grp|
allow(grp).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
allow_next_found_instance_of(Group) do |group|
allow(group).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
end
page.refresh
expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
@ -515,8 +515,12 @@ RSpec.describe 'Project' do
end
context 'with storage_enforcement_date not set' do
# This test should break and be rewritten after the implementation of the storage_enforcement_date
# TBD: https://gitlab.com/gitlab-org/gitlab/-/issues/350632
before do
allow_next_found_instance_of(Group) do |group|
allow(group).to receive(:storage_enforcement_date).and_return(nil)
end
end
it 'does not display the banner in the group page' do
stub_feature_flags(namespace_storage_limit_bypass_date_check: false)
visit project_path(project)
@ -526,11 +530,11 @@ RSpec.describe 'Project' do
end
def expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
expect(page).to have_text "From #{storage_enforcement_date} storage limits will apply to this namespace"
expect(page).to have_text "Effective #{storage_enforcement_date}, namespace storage limits will apply"
end
def expect_page_not_to_have_storage_enforcement_banner
expect(page).not_to have_text "storage limits will apply to this namespace"
expect(page).not_to have_text "namespace storage limits will apply"
end
def remove_with_confirm(button_text, confirm_with, confirm_button_text = 'Confirm')

View File

@ -1,12 +1,12 @@
import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { NodeViewWrapper } from '@tiptap/vue-2';
import { selectedRect as getSelectedRect } from 'prosemirror-tables';
import { selectedRect as getSelectedRect } from '@_ueberdosis/prosemirror-tables';
import { nextTick } from 'vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import TableCellBaseWrapper from '~/content_editor/components/wrappers/table_cell_base.vue';
import { createTestEditor, mockChainedCommands, emitEditorEvent } from '../../test_utils';
jest.mock('prosemirror-tables');
jest.mock('@_ueberdosis/prosemirror-tables');
describe('content/components/wrappers/table_cell_base', () => {
let wrapper;

View File

@ -1,6 +1,6 @@
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import { GlDropdown, GlSearchBoxByType, GlDropdownItem } from '@gitlab/ui';
import { GlDropdown, GlSearchBoxByType, GlDropdownItem, GlSprintf } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import BranchDropdown, {
i18n,
@ -36,15 +36,20 @@ describe('Branch dropdown', () => {
await waitForPromises();
};
const findGlDropdown = () => wrapper.find(GlDropdown);
const findAllBranches = () => wrapper.findAll(GlDropdownItem);
const findGlDropdown = () => wrapper.findComponent(GlDropdown);
const findAllBranches = () => wrapper.findAllComponents(GlDropdownItem);
const findNoDataMsg = () => wrapper.findByTestId('no-data');
const findGlSearchBoxByType = () => wrapper.find(GlSearchBoxByType);
const findGlSearchBoxByType = () => wrapper.findComponent(GlSearchBoxByType);
const findWildcardButton = () => wrapper.findByTestId('create-wildcard-button');
const findHelpText = () => wrapper.findComponent(GlSprintf);
const setSearchTerm = (searchTerm) => findGlSearchBoxByType().vm.$emit('input', searchTerm);
beforeEach(() => createComponent());
afterEach(() => {
wrapper.destroy();
});
it('renders a GlDropdown component with the correct props', () => {
expect(findGlDropdown().props()).toMatchObject({ text: value });
});
@ -85,6 +90,10 @@ describe('Branch dropdown', () => {
findWildcardButton().vm.$emit('click');
expect(wrapper.emitted('createWildcard')).toEqual([[searchTerm]]);
});
it('renders help text', () => {
expect(findHelpText().attributes('message')).toBe(i18n.branchHelpText);
});
});
it('displays an error message if fetch failed', async () => {

View File

@ -0,0 +1,57 @@
import { nextTick } from 'vue';
import { GlLink } from '@gitlab/ui';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import Protections, {
i18n,
} from '~/projects/settings/branch_rules/components/protections/index.vue';
import PushProtections from '~/projects/settings/branch_rules/components/protections/push_protections.vue';
import MergeProtections from '~/projects/settings/branch_rules/components/protections/merge_protections.vue';
import { protections } from '../../mock_data';
describe('Branch Protections', () => {
let wrapper;
const createComponent = async () => {
wrapper = mountExtended(Protections, {
propsData: { protections },
});
await nextTick();
};
const findHeading = () => wrapper.find('h4');
const findHelpText = () => wrapper.findByTestId('protections-help-text');
const findHelpLink = () => wrapper.findComponent(GlLink);
const findPushProtections = () => wrapper.findComponent(PushProtections);
const findMergeProtections = () => wrapper.findComponent(MergeProtections);
beforeEach(() => createComponent());
afterEach(() => {
wrapper.destroy();
});
it('renders a heading', () => {
expect(findHeading().text()).toBe(i18n.protections);
});
it('renders help text', () => {
expect(findHelpText().text()).toMatchInterpolatedText(i18n.protectionsHelpText);
expect(findHelpLink().attributes('href')).toBe('/help/user/project/protected_branches');
});
it('renders a PushProtections component with correct props', () => {
expect(findPushProtections().props('membersAllowedToPush')).toStrictEqual(
protections.membersAllowedToPush,
);
expect(findPushProtections().props('allowForcePush')).toBe(protections.allowForcePush);
});
it('renders a MergeProtections component with correct props', () => {
expect(findMergeProtections().props('membersAllowedToMerge')).toStrictEqual(
protections.membersAllowedToMerge,
);
expect(findMergeProtections().props('requireCodeOwnersApproval')).toBe(
protections.requireCodeOwnersApproval,
);
});
});

View File

@ -0,0 +1,53 @@
import { GlFormGroup, GlFormCheckbox } from '@gitlab/ui';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import MergeProtections, {
i18n,
} from '~/projects/settings/branch_rules/components/protections/merge_protections.vue';
import { membersAllowedToMerge, requireCodeOwnersApproval } from '../../mock_data';
describe('Merge Protections', () => {
let wrapper;
const propsData = {
membersAllowedToMerge,
requireCodeOwnersApproval,
};
const createComponent = () => {
wrapper = mountExtended(MergeProtections, {
propsData,
});
};
const findFormGroup = () => wrapper.findComponent(GlFormGroup);
const findCodeOwnersApprovalCheckbox = () => wrapper.findComponent(GlFormCheckbox);
beforeEach(() => createComponent());
afterEach(() => {
wrapper.destroy();
});
it('renders a form group with the correct label', () => {
expect(findFormGroup().text()).toContain(i18n.allowedToMerge);
});
describe('Require code owners approval checkbox', () => {
it('renders a checkbox with the correct props', () => {
expect(findCodeOwnersApprovalCheckbox().vm.$attrs.checked).toBe(
propsData.requireCodeOwnersApproval,
);
});
it('renders help text', () => {
expect(findCodeOwnersApprovalCheckbox().text()).toContain(i18n.requireApprovalTitle);
expect(findCodeOwnersApprovalCheckbox().text()).toContain(i18n.requireApprovalHelpText);
});
it('emits a change-allow-force-push event when changed', () => {
findCodeOwnersApprovalCheckbox().vm.$emit('change', false);
expect(wrapper.emitted('change-require-code-owners-approval')[0]).toEqual([false]);
});
});
});

View File

@ -0,0 +1,50 @@
import { GlFormGroup, GlSprintf, GlFormCheckbox } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import PushProtections, {
i18n,
} from '~/projects/settings/branch_rules/components/protections/push_protections.vue';
import { membersAllowedToPush, allowForcePush } from '../../mock_data';
describe('Push Protections', () => {
let wrapper;
const propsData = {
membersAllowedToPush,
allowForcePush,
};
const createComponent = () => {
wrapper = shallowMountExtended(PushProtections, {
propsData,
});
};
const findFormGroup = () => wrapper.findComponent(GlFormGroup);
const findAllowForcePushCheckbox = () => wrapper.findComponent(GlFormCheckbox);
const findHelpText = () => wrapper.findComponent(GlSprintf);
beforeEach(() => createComponent());
afterEach(() => {
wrapper.destroy();
});
it('renders a form group with the correct label', () => {
expect(findFormGroup().attributes('label')).toBe(i18n.allowedToPush);
});
describe('Allow force push checkbox', () => {
it('renders a checkbox with the correct props', () => {
expect(findAllowForcePushCheckbox().vm.$attrs.checked).toBe(propsData.allowForcePush);
});
it('renders help text', () => {
expect(findHelpText().attributes('message')).toBe(i18n.forcePushTitle);
});
it('emits a change-allow-force-push event when changed', () => {
findAllowForcePushCheckbox().vm.$emit('change', false);
expect(wrapper.emitted('change-allow-force-push')[0]).toEqual([false]);
});
});
});

View File

@ -0,0 +1,10 @@
export const membersAllowedToPush = ['Maintainers', 'Developers'];
export const allowForcePush = false;
export const membersAllowedToMerge = ['Maintainers'];
export const requireCodeOwnersApproval = false;
export const protections = {
membersAllowedToPush,
allowForcePush,
membersAllowedToMerge,
requireCodeOwnersApproval,
};

View File

@ -3,9 +3,12 @@ import { getParameterByName } from '~/lib/utils/url_utility';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import RuleEdit from '~/projects/settings/branch_rules/components/rule_edit.vue';
import BranchDropdown from '~/projects/settings/branch_rules/components/branch_dropdown.vue';
import Protections from '~/projects/settings/branch_rules/components/protections/index.vue';
jest.mock('~/lib/utils/url_utility', () => ({
getParameterByName: jest.fn().mockImplementation(() => 'main'),
joinPaths: jest.fn(),
setUrlFragment: jest.fn(),
}));
describe('Edit branch rule', () => {
@ -16,10 +19,15 @@ describe('Edit branch rule', () => {
wrapper = shallowMountExtended(RuleEdit, { propsData: { projectPath } });
};
const findBranchDropdown = () => wrapper.find(BranchDropdown);
const findBranchDropdown = () => wrapper.findComponent(BranchDropdown);
const findProtections = () => wrapper.findComponent(Protections);
beforeEach(() => createComponent());
afterEach(() => {
wrapper.destroy();
});
it('gets the branch param from url', () => {
expect(getParameterByName).toHaveBeenCalledWith('branch');
});
@ -46,4 +54,55 @@ describe('Edit branch rule', () => {
expect(findBranchDropdown().props('value')).toBe(wildcard);
});
});
describe('Protections', () => {
it('renders a Protections component with the correct props', () => {
expect(findProtections().props('protections')).toMatchObject({
membersAllowedToPush: [],
allowForcePush: false,
membersAllowedToMerge: [],
requireCodeOwnersApproval: false,
});
});
it('updates protections when change-allowed-to-push-members is emitted', async () => {
const membersAllowedToPush = ['test'];
findProtections().vm.$emit('change-allowed-to-push-members', membersAllowedToPush);
await nextTick();
expect(findProtections().props('protections')).toEqual(
expect.objectContaining({ membersAllowedToPush }),
);
});
it('updates protections when change-allow-force-push is emitted', async () => {
const allowForcePush = true;
findProtections().vm.$emit('change-allow-force-push', allowForcePush);
await nextTick();
expect(findProtections().props('protections')).toEqual(
expect.objectContaining({ allowForcePush }),
);
});
it('updates protections when change-allowed-to-merge-members is emitted', async () => {
const membersAllowedToMerge = ['test'];
findProtections().vm.$emit('change-allowed-to-merge-members', membersAllowedToMerge);
await nextTick();
expect(findProtections().props('protections')).toEqual(
expect.objectContaining({ membersAllowedToMerge }),
);
});
it('updates protections when change-require-code-owners-approval is emitted', async () => {
const requireCodeOwnersApproval = true;
findProtections().vm.$emit('change-require-code-owners-approval', requireCodeOwnersApproval);
await nextTick();
expect(findProtections().props('protections')).toEqual(
expect.objectContaining({ requireCodeOwnersApproval }),
);
});
});
});

View File

@ -57,8 +57,8 @@ RSpec.describe StorageHelper do
let_it_be(:paid_group) { create(:group) }
before do
allow(helper).to receive(:can?).with(current_user, :maintain_namespace, free_group).and_return(true)
allow(helper).to receive(:can?).with(current_user, :maintain_namespace, paid_group).and_return(true)
allow(helper).to receive(:can?).with(current_user, :maintainer_access, free_group).and_return(true)
allow(helper).to receive(:can?).with(current_user, :maintainer_access, paid_group).and_return(true)
allow(helper).to receive(:current_user) { current_user }
allow(paid_group).to receive(:paid?).and_return(true)
@ -84,7 +84,7 @@ RSpec.describe StorageHelper do
end
it 'returns nil when current_user do not have access usage quotas page' do
allow(helper).to receive(:can?).with(current_user, :maintain_namespace, free_group).and_return(false)
allow(helper).to receive(:can?).with(current_user, :maintainer_access, free_group).and_return(false)
expect(helper.storage_enforcement_banner_info(free_group)).to be(nil)
end
@ -97,12 +97,16 @@ RSpec.describe StorageHelper do
context 'when current_user can access the usage quotas page' do
it 'returns a hash' do
used_storage = helper.storage_counter(free_group.root_storage_statistics&.storage_size || 0)
expect(helper.storage_enforcement_banner_info(free_group)).to eql({
text: "From #{storage_enforcement_date} storage limits will apply to this namespace. You are currently using 0 Bytes of namespace storage. View and manage your usage from <strong>Group settings &gt; Usage quotas</strong>.",
text_paragraph_1: "Effective #{storage_enforcement_date}, <a href=\"https://forum.gitlab.com/t/gitlab-introduces-storage-and-transfer-limits-for-users-on-saas/69883\" >namespace storage limits will apply</a> to the <strong>#{free_group.name}</strong> namespace. View the <a href=\"/help/user/usage_quotas#tbd\" >rollout schedule for this change</a>.",
text_paragraph_2: "The namespace is currently using <strong>#{used_storage}</strong> of namespace storage. View and manage your usage from <strong>Group settings &gt; Usage quotas</strong>. <a href=\"/help/user/usage_quotas#manage-your-storage-usage\" >Learn more</a> about how to reduce your storage.",
text_paragraph_3: "See our <a href=\"https://about.gitlab.com/pricing/faq-efficient-free-tier/#storage-and-transfer-limits-on-gitlab-saas-free-tier\" >FAQ</a> for more information.",
variant: 'warning',
namespace_id: free_group.id,
callouts_feature_name: 'storage_enforcement_banner_second_enforcement_threshold',
callouts_path: '/-/users/group_callouts',
learn_more_link: '<a rel="noopener noreferrer" target="_blank" href="/help//">Learn more.</a>'
callouts_path: '/-/users/group_callouts'
})
end
@ -112,7 +116,7 @@ RSpec.describe StorageHelper do
end
it 'returns a hash with the correct storage size text' do
expect(helper.storage_enforcement_banner_info(free_group)[:text]).to eql("From #{storage_enforcement_date} storage limits will apply to this namespace. You are currently using 100 KB of namespace storage. View and manage your usage from <strong>Group settings &gt; Usage quotas</strong>.")
expect(helper.storage_enforcement_banner_info(free_group)[:text_paragraph_2]).to eql("The namespace is currently using <strong>100 KB</strong> of namespace storage. View and manage your usage from <strong>Group settings &gt; Usage quotas</strong>. <a href=\"/help/user/usage_quotas#manage-your-storage-usage\" >Learn more</a> about how to reduce your storage.")
end
end
@ -120,11 +124,12 @@ RSpec.describe StorageHelper do
let_it_be(:sub_group) { build(:group) }
before do
allow(helper).to receive(:can?).with(current_user, :maintainer_access, sub_group).and_return(true)
allow(sub_group).to receive(:root_ancestor).and_return(free_group)
end
it 'returns the banner hash' do
expect(helper.storage_enforcement_banner_info(sub_group).keys).to match_array(%i(text variant callouts_feature_name callouts_path learn_more_link))
expect(helper.storage_enforcement_banner_info(sub_group).keys).to match_array(%i(text_paragraph_1 text_paragraph_2 text_paragraph_3 variant namespace_id callouts_feature_name callouts_path))
end
end
end
@ -136,7 +141,7 @@ RSpec.describe StorageHelper do
end
it 'returns the enforcement info' do
expect(helper.storage_enforcement_banner_info(free_group)[:text]).to include("From #{Date.current} storage limits will apply to this namespace.")
expect(helper.storage_enforcement_banner_info(free_group)[:text_paragraph_1]).to include("Effective #{Date.current}, <a href=\"https://forum.gitlab.com/t/gitlab-introduces-storage-and-transfer-limits-for-users-on-saas/69883\" >namespace storage limits will apply</a>")
end
end

View File

@ -0,0 +1,54 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::BackgroundMigration::BackfillNamespaceIdOfVulnerabilityReads, schema: 20220722145845 do
let(:namespaces) { table(:namespaces) }
let(:projects) { table(:projects) }
let(:users) { table(:users) }
let(:scanners) { table(:vulnerability_scanners) }
let(:vulnerabilities) { table(:vulnerabilities) }
let(:vulnerability_reads) { table(:vulnerability_reads) }
let(:namespace) { namespaces.create!(name: 'user', path: 'user') }
let(:project) { projects.create!(namespace_id: namespace.id, project_namespace_id: namespace.id) }
let(:user) { users.create!(username: 'john_doe', email: 'johndoe@gitlab.com', projects_limit: 10) }
let(:scanner) { scanners.create!(project_id: project.id, external_id: 'external_id', name: 'Test Scanner') }
let(:vulnerability) do
vulnerabilities.create!(
project_id: project.id,
author_id: user.id,
title: 'test',
severity: 1,
confidence: 1,
report_type: 1
)
end
let(:vulnerability_read) do
vulnerability_reads.create!(
project_id: project.id,
vulnerability_id: vulnerability.id,
scanner_id: scanner.id,
severity: 1,
report_type: 1,
state: 1,
uuid: SecureRandom.uuid
)
end
subject(:perform_migration) do
described_class.new(start_id: vulnerability_read.vulnerability_id,
end_id: vulnerability_read.vulnerability_id,
batch_table: :vulnerability_reads,
batch_column: :vulnerability_id,
sub_batch_size: 1,
pause_ms: 0,
connection: ActiveRecord::Base.connection)
.perform
end
it 'sets the namespace_id of existing record' do
expect { perform_migration }.to change { vulnerability_read.reload.namespace_id }.from(nil).to(namespace.id)
end
end

View File

@ -1,52 +0,0 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::BackgroundMigration::CopyCiBuildsColumnsToSecurityScans,
:suppress_gitlab_schemas_validate_connection, schema: 20210728174349 do
let(:migration) { described_class.new }
let_it_be(:namespaces) { table(:namespaces) }
let_it_be(:projects) { table(:projects) }
let_it_be(:ci_pipelines) { table(:ci_pipelines) }
let_it_be(:ci_builds) { table(:ci_builds) }
let_it_be(:security_scans) { table(:security_scans) }
let!(:namespace) { namespaces.create!(name: 'namespace', path: 'namespace') }
let!(:project1) { projects.create!(namespace_id: namespace.id) }
let!(:project2) { projects.create!(namespace_id: namespace.id) }
let!(:pipeline1) { ci_pipelines.create!(status: "success")}
let!(:pipeline2) { ci_pipelines.create!(status: "success")}
let!(:build1) { ci_builds.create!(commit_id: pipeline1.id, type: 'Ci::Build', project_id: project1.id) }
let!(:build2) { ci_builds.create!(commit_id: pipeline2.id, type: 'Ci::Build', project_id: project2.id) }
let!(:build3) { ci_builds.create!(commit_id: pipeline1.id, type: 'Ci::Build', project_id: project1.id) }
let!(:scan1) { security_scans.create!(build_id: build1.id, scan_type: 1) }
let!(:scan2) { security_scans.create!(build_id: build2.id, scan_type: 1) }
let!(:scan3) { security_scans.create!(build_id: build3.id, scan_type: 1) }
subject { migration.perform(scan1.id, scan2.id) }
before do
stub_const("#{described_class}::UPDATE_BATCH_SIZE", 2)
end
it 'copies `project_id`, `commit_id` from `ci_builds` to `security_scans`', :aggregate_failures do
expect(migration).to receive(:mark_job_as_succeeded).with(scan1.id, scan2.id)
subject
scan1.reload
expect(scan1.project_id).to eq(project1.id)
expect(scan1.pipeline_id).to eq(pipeline1.id)
scan2.reload
expect(scan2.project_id).to eq(project2.id)
expect(scan2.pipeline_id).to eq(pipeline2.id)
scan3.reload
expect(scan3.project_id).to be_nil
expect(scan3.pipeline_id).to be_nil
end
end

View File

@ -51,14 +51,6 @@ RSpec.describe Gitlab::Ci::Build::Rules::Rule::Clause::If do
end
it { is_expected.to eq(true) }
context 'when the FF ci_fix_rules_if_comparison_with_regexp_variable is disabled' do
before do
stub_feature_flags(ci_fix_rules_if_comparison_with_regexp_variable: false)
end
it { is_expected.to eq(false) }
end
end
context 'when comparison is false' do

View File

@ -160,14 +160,6 @@ RSpec.describe Gitlab::Ci::Pipeline::Expression::Lexeme::Matches do
let(:left_value) { 'abcde' }
it { is_expected.to eq(true) }
context 'when the FF ci_fix_rules_if_comparison_with_regexp_variable is disabled' do
before do
stub_feature_flags(ci_fix_rules_if_comparison_with_regexp_variable: false)
end
it { is_expected.to eq(false) }
end
end
context 'when not matching' do

View File

@ -160,14 +160,6 @@ RSpec.describe Gitlab::Ci::Pipeline::Expression::Lexeme::NotMatches do
let(:left_value) { 'abcde' }
it { is_expected.to eq(false) }
context 'when the FF ci_fix_rules_if_comparison_with_regexp_variable is disabled' do
before do
stub_feature_flags(ci_fix_rules_if_comparison_with_regexp_variable: false)
end
it { is_expected.to eq(true) }
end
end
context 'when not matching' do

View File

@ -179,24 +179,16 @@ RSpec.describe Gitlab::Ci::Pipeline::Expression::Statement do
.to_hash
end
where(:expression, :ff, :result) do
'$teststring =~ "abcde"' | true | true
'$teststring =~ "abcde"' | false | true
'$teststring =~ $teststring' | true | true
'$teststring =~ $teststring' | false | true
'$teststring =~ $pattern1' | true | true
'$teststring =~ $pattern1' | false | false
'$teststring =~ $pattern2' | true | false
'$teststring =~ $pattern2' | false | false
where(:expression, :result) do
'$teststring =~ "abcde"' | true
'$teststring =~ $teststring' | true
'$teststring =~ $pattern1' | true
'$teststring =~ $pattern2' | false
end
with_them do
let(:text) { expression }
before do
stub_feature_flags(ci_fix_rules_if_comparison_with_regexp_variable: ff)
end
it { is_expected.to eq(result) }
end
end

View File

@ -12,8 +12,9 @@ RSpec.describe Gitlab::GithubImport::Importer::Events::CrossReferenced, :clean_g
let(:client) { instance_double('Gitlab::GithubImport::Client') }
let(:user_finder) { Gitlab::GithubImport::UserFinder.new(project, client) }
let(:issue) { create(:issue, project: project) }
let(:referenced_in) { build_stubbed(:issue, project: project) }
let(:issue_iid) { 999 }
let(:issue) { create(:issue, project: project, iid: issue_iid) }
let(:referenced_in) { build_stubbed(:issue, project: project, iid: issue_iid + 1) }
let(:commit_id) { nil }
let(:issue_event) do
@ -49,7 +50,7 @@ RSpec.describe Gitlab::GithubImport::Importer::Events::CrossReferenced, :clean_g
end
context 'when referenced in other issue' do
let(:expected_note_body) { "mentioned in issue ##{issue.iid}" }
let(:expected_note_body) { "mentioned in issue ##{referenced_in.iid}" }
before do
other_issue_resource = sawyer_stub.new(iid: referenced_in.iid, issuable_type: 'Issue')
@ -58,7 +59,7 @@ RSpec.describe Gitlab::GithubImport::Importer::Events::CrossReferenced, :clean_g
allow(user_finder).to receive(:find).with(user.id, user.username).and_return(user.id)
end
it 'creates expected note', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/368827' do
it 'creates expected note' do
importer.execute(issue_event)
expect(issue.notes.count).to eq 1

View File

@ -160,6 +160,38 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DatabaseMetric do
end
end
end
context 'with custom timestamp column' do
subject do
described_class.tap do |metric_class|
metric_class.relation { Issue }
metric_class.operation :count
metric_class.timestamp_column :last_edited_at
end.new(time_frame: '28d')
end
it 'calculates a correct result' do
create(:issue, last_edited_at: 5.days.ago)
expect(subject.value).to eq(1)
end
end
context 'with default timestamp column' do
subject do
described_class.tap do |metric_class|
metric_class.relation { Issue }
metric_class.operation :count
end.new(time_frame: '28d')
end
it 'calculates a correct result' do
create(:issue, last_edited_at: 5.days.ago)
create(:issue, created_at: 5.days.ago)
expect(subject.value).to eq(1)
end
end
end
context 'with unimplemented operation method used' do

View File

@ -3,74 +3,8 @@
require 'spec_helper'
require_migration!
RSpec.describe AssociateExistingDastBuildsWithVariables, :suppress_gitlab_schemas_validate_connection do
subject(:migration) { described_class.new }
let_it_be(:namespaces_table) { table(:namespaces) }
let_it_be(:projects_table) { table(:projects) }
let_it_be(:ci_pipelines_table) { table(:ci_pipelines) }
let_it_be(:ci_builds_table) { table(:ci_builds) }
let_it_be(:dast_sites_table) { table(:dast_sites) }
let_it_be(:dast_site_profiles_table) { table(:dast_site_profiles) }
let_it_be(:dast_scanner_profiles_table) { table(:dast_scanner_profiles) }
let_it_be(:dast_site_profiles_builds_table) { table(:dast_site_profiles_builds) }
let_it_be(:dast_profiles_table) { table(:dast_profiles) }
let_it_be(:dast_profiles_pipelines_table) { table(:dast_profiles_pipelines) }
let!(:group) { namespaces_table.create!(type: 'Group', name: 'group', path: 'group') }
let!(:project) { projects_table.create!(name: 'project', path: 'project', namespace_id: group.id) }
let!(:pipeline_0) { ci_pipelines_table.create!(project_id: project.id, source: 13) }
let!(:pipeline_1) { ci_pipelines_table.create!(project_id: project.id, source: 13) }
let!(:build_0) { ci_builds_table.create!(project_id: project.id, commit_id: pipeline_0.id, name: :dast, stage: :dast) }
let!(:build_1) { ci_builds_table.create!(project_id: project.id, commit_id: pipeline_0.id, name: :dast, stage: :dast) }
let!(:build_2) { ci_builds_table.create!(project_id: project.id, commit_id: pipeline_1.id, name: :dast, stage: :dast) }
let!(:build_3) { ci_builds_table.create!(project_id: project.id, commit_id: pipeline_1.id, name: :dast) }
let!(:build_4) { ci_builds_table.create!(project_id: project.id, commit_id: pipeline_1.id, stage: :dast) }
let!(:dast_site) { dast_sites_table.create!(project_id: project.id, url: generate(:url)) }
let!(:dast_site_profile) { dast_site_profiles_table.create!(project_id: project.id, dast_site_id: dast_site.id, name: SecureRandom.hex) }
let!(:dast_scanner_profile) { dast_scanner_profiles_table.create!(project_id: project.id, name: SecureRandom.hex) }
let!(:dast_profile) do
dast_profiles_table.create!(
project_id: project.id,
dast_site_profile_id: dast_site_profile.id,
dast_scanner_profile_id: dast_scanner_profile.id,
name: SecureRandom.hex,
description: SecureRandom.hex
)
end
let!(:dast_profiles_pipeline_0) { dast_profiles_pipelines_table.create!(dast_profile_id: dast_profile.id, ci_pipeline_id: pipeline_0.id) }
let!(:dast_profiles_pipeline_1) { dast_profiles_pipelines_table.create!(dast_profile_id: dast_profile.id, ci_pipeline_id: pipeline_1.id) }
context 'when there are ci_pipelines with associated dast_profiles' do
describe 'migration up' do
it 'adds association of dast_site_profiles to ci_builds', :aggregate_failures do
expect(dast_site_profiles_builds_table.all).to be_empty
migration.up
expected_results = [
[dast_site_profile.id, build_0.id],
[dast_site_profile.id, build_1.id],
[dast_site_profile.id, build_2.id]
]
expect(dast_site_profiles_builds_table.all.map { |assoc| [assoc.dast_site_profile_id, assoc.ci_build_id] }).to contain_exactly(*expected_results)
end
end
end
describe 'migration down' do
it 'deletes all records in the dast_site_profiles_builds table', :aggregate_failures do
expect(dast_site_profiles_builds_table.all).to be_empty
migration.up
migration.down
expect(dast_site_profiles_builds_table.all).to be_empty
end
RSpec.describe AssociateExistingDastBuildsWithVariables do
it 'is a no-op' do
migrate!
end
end

View File

@ -3,42 +3,8 @@
require 'spec_helper'
require_migration!
RSpec.describe DisableJobTokenScopeWhenUnused, :suppress_gitlab_schemas_validate_connection do
let(:ci_cd_settings) { table(:project_ci_cd_settings) }
let(:links) { table(:ci_job_token_project_scope_links) }
let(:namespaces) { table(:namespaces) }
let(:projects) { table(:projects) }
let(:namespace) { namespaces.create!(name: 'test', path: 'path', type: 'Group') }
let(:project_with_used_scope) { projects.create!(namespace_id: namespace.id) }
let!(:used_scope_settings) { ci_cd_settings.create!(project_id: project_with_used_scope.id, job_token_scope_enabled: true) }
let(:target_project) { projects.create!(namespace_id: namespace.id) }
let!(:link) { links.create!(source_project_id: project_with_used_scope.id, target_project_id: target_project.id) }
let(:project_with_unused_scope) { projects.create!(namespace_id: namespace.id) }
let!(:unused_scope_settings) { ci_cd_settings.create!(project_id: project_with_unused_scope.id, job_token_scope_enabled: true) }
let(:project_with_disabled_scope) { projects.create!(namespace_id: namespace.id) }
let!(:disabled_scope_settings) { ci_cd_settings.create!(project_id: project_with_disabled_scope.id, job_token_scope_enabled: false) }
describe '#up' do
it 'sets job_token_scope_enabled to false for projects not having job token scope configured' do
migrate!
expect(unused_scope_settings.reload.job_token_scope_enabled).to be_falsey
end
it 'keeps the scope enabled for projects that are using it' do
migrate!
expect(used_scope_settings.reload.job_token_scope_enabled).to be_truthy
end
it 'keeps the scope disabled for projects having it disabled' do
migrate!
expect(disabled_scope_settings.reload.job_token_scope_enabled).to be_falsey
end
RSpec.describe DisableJobTokenScopeWhenUnused do
it 'is a no-op' do
migrate!
end
end

View File

@ -0,0 +1,32 @@
# frozen_string_literal: true
require 'spec_helper'
require_migration!
RSpec.describe ScheduleBackfillingTheNamespaceIdForVulnerabilityReads do
let_it_be(:migration) { described_class::MIGRATION_NAME }
describe '#up' do
it 'schedules background jobs for each batch of vulnerabilities' do
migrate!
expect(migration).to have_scheduled_batched_migration(
table_name: :vulnerability_reads,
column_name: :vulnerability_id,
interval: 2.minutes,
batch_size: 10_000,
sub_batch_size: 200
)
end
end
describe '#down' do
it 'deletes all batched migration records' do
migrate!
schema_migrate_down!
expect(migration).not_to have_scheduled_batched_migration
end
end
end

View File

@ -3,50 +3,8 @@
require 'spec_helper'
require_migration!
RSpec.describe ScheduleCopyCiBuildsColumnsToSecurityScans2, :suppress_gitlab_schemas_validate_connection do
let_it_be(:namespaces) { table(:namespaces) }
let_it_be(:projects) { table(:projects) }
let_it_be(:ci_pipelines) { table(:ci_pipelines) }
let_it_be(:ci_builds) { table(:ci_builds) }
let_it_be(:security_scans) { table(:security_scans) }
let_it_be(:background_migration_jobs) { table(:background_migration_jobs) }
let!(:namespace) { namespaces.create!(name: 'namespace', path: 'namespace') }
let!(:project) { projects.create!(namespace_id: namespace.id) }
let!(:pipeline) { ci_pipelines.create!(status: "success")}
let!(:build1) { ci_builds.create!(commit_id: pipeline.id, type: 'Ci::Build', project_id: project.id) }
let!(:build2) { ci_builds.create!(commit_id: pipeline.id, type: 'Ci::Build', project_id: project.id) }
let!(:build3) { ci_builds.create!(commit_id: pipeline.id, type: 'Ci::Build', project_id: project.id) }
let!(:scan1) { security_scans.create!(build_id: build1.id, scan_type: 1) }
let!(:scan2) { security_scans.create!(build_id: build2.id, scan_type: 1) }
let!(:scan3) { security_scans.create!(build_id: build3.id, scan_type: 1) }
let!(:job_class_name) { described_class::MIGRATION }
let!(:tracked_pending_job) { background_migration_jobs.create!(class_name: job_class_name, status: 0, arguments: [1]) }
let!(:tracked_successful_job) { background_migration_jobs.create!(class_name: job_class_name, status: 1, arguments: [2]) }
let(:jobs) { Gitlab::Database::BackgroundMigrationJob.where(id: [tracked_pending_job.id, tracked_successful_job.id] ).for_migration_class(job_class_name) }
before do
stub_const("#{described_class}::BATCH_SIZE", 2)
allow_next_instance_of(Gitlab::BackgroundMigration::CopyCiBuildsColumnsToSecurityScans) do |instance|
allow(instance).to receive(:mark_job_as_succeeded)
end
end
around do |example|
freeze_time { Sidekiq::Testing.fake! { example.run } }
end
it 'schedules background migrations', :aggregate_failures do
expect(jobs).not_to be_empty
RSpec.describe ScheduleCopyCiBuildsColumnsToSecurityScans2 do
it 'is a no-op' do
migrate!
expect(jobs).to be_empty
expect(BackgroundMigrationWorker.jobs.size).to eq(2)
expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, scan1.id, scan2.id)
expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, scan3.id, scan3.id)
end
end

View File

@ -2283,9 +2283,8 @@ RSpec.describe Namespace do
stub_feature_flags(namespace_storage_limit_bypass_date_check: false)
end
# Date TBD: https://gitlab.com/gitlab-org/gitlab/-/issues/350632
it 'returns nil' do
expect(namespace.storage_enforcement_date).to be(nil)
it 'returns correct date' do
expect(namespace.storage_enforcement_date).to eql(Date.new(2022, 10, 19))
end
context 'when :storage_banner_bypass_date_check is enabled' do

View File

@ -1,6 +1 @@
- "./spec/lib/gitlab/background_migration/copy_ci_builds_columns_to_security_scans_spec.rb"
- "./spec/lib/gitlab/background_migration/migrate_pages_metadata_spec.rb"
- "./spec/migrations/20210907211557_finalize_ci_builds_bigint_conversion_spec.rb"
- "./spec/migrations/associate_existing_dast_builds_with_variables_spec.rb"
- "./spec/migrations/disable_job_token_scope_when_unused_spec.rb"
- "./spec/migrations/schedule_copy_ci_builds_columns_to_security_scans2_spec.rb"

649
yarn.lock
View File

@ -2,6 +2,17 @@
# yarn lockfile v1
"@_ueberdosis/prosemirror-tables@1.1.3", "@_ueberdosis/prosemirror-tables@^1.1.3":
version "1.1.3"
resolved "https://registry.yarnpkg.com/@_ueberdosis/prosemirror-tables/-/prosemirror-tables-1.1.3.tgz#56fdbc8b1d6ec43e7b7beb21e213c131eec451cd"
integrity sha512-su3pbFi1DT89g6Cuh72TE0MWWKHmWgHcQJ3ODRkm6XfIppWaGpU49t02ur3sgJc7hUhfQXjB93aSkDgOmIii2w==
dependencies:
prosemirror-keymap "^1.1.2"
prosemirror-model "^1.8.1"
prosemirror-state "^1.3.1"
prosemirror-transform "^1.2.1"
prosemirror-view "^1.13.3"
"@ampproject/remapping@^2.1.0":
version "2.1.2"
resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.1.2.tgz#4edca94973ded9630d20101cd8559cedb8d8bd34"
@ -1639,228 +1650,215 @@
dom-accessibility-api "^0.5.1"
pretty-format "^26.4.2"
"@tiptap/core@^2.0.0-beta.176":
version "2.0.0-beta.176"
resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-2.0.0-beta.176.tgz#a8bb9b57d2ecf77b6cd02340324626ef3e336a15"
integrity sha512-Gs/+yUYTNpt8PnclEHbfBnY56D/9PpKTyzrg8VZwCFK9S69aVD2dqLsYs/Gn+EjzKImXRAiqSe1/FWcNEDkmCg==
"@tiptap/core@^2.0.0-beta.182":
version "2.0.0-beta.182"
resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-2.0.0-beta.182.tgz#d2001e9b765adda95e15d171479860a3349e2d04"
integrity sha512-MZGkMGnVnWhBzjvpBNwQ9zBz38ndi3Irbf90uCTSArR0kaCVkW4vmyuPuOXd+0SO8Yv/l5oyDdOCpaG3rnQYfw==
dependencies:
"@types/prosemirror-commands" "^1.0.4"
"@types/prosemirror-keymap" "^1.0.4"
"@types/prosemirror-model" "^1.16.0"
"@types/prosemirror-schema-list" "^1.0.3"
"@types/prosemirror-state" "^1.2.8"
"@types/prosemirror-transform" "^1.1.5"
"@types/prosemirror-view" "^1.23.1"
prosemirror-commands "^1.2.1"
prosemirror-keymap "^1.1.5"
prosemirror-model "^1.16.1"
prosemirror-schema-list "^1.1.6"
prosemirror-state "^1.3.4"
prosemirror-transform "^1.3.3"
prosemirror-view "^1.23.6"
prosemirror-commands "1.3.0"
prosemirror-keymap "1.2.0"
prosemirror-model "1.18.1"
prosemirror-schema-list "1.2.0"
prosemirror-state "1.4.1"
prosemirror-transform "1.6.0"
prosemirror-view "1.26.2"
"@tiptap/extension-blockquote@^2.0.0-beta.26":
version "2.0.0-beta.26"
resolved "https://registry.yarnpkg.com/@tiptap/extension-blockquote/-/extension-blockquote-2.0.0-beta.26.tgz#e5ae4b7bd9376db37407a23e22080c7b11287f3b"
integrity sha512-A6yjcYovONJfOjQFk6vDYXswaCdCtCwjL7w9VTB0R2DLTuJvvRt9DWN0IDcMrj5G+aMgDq4GUUTitv+2Y8krDg==
"@tiptap/extension-blockquote@^2.0.0-beta.29":
version "2.0.0-beta.29"
resolved "https://registry.yarnpkg.com/@tiptap/extension-blockquote/-/extension-blockquote-2.0.0-beta.29.tgz#6f1c4b17efa6457c7776f32d0807e96d848d4389"
integrity sha512-zMYT5TtpKWav9VhTn4JLyMvXmhEdbD6on0MdhcTjRm0I5ugyR4ZbJwh2aelM7G9DZVYzB8jZU18OSDJmo7Af7w==
"@tiptap/extension-bold@^2.0.0-beta.26":
version "2.0.0-beta.26"
resolved "https://registry.yarnpkg.com/@tiptap/extension-bold/-/extension-bold-2.0.0-beta.26.tgz#aa1c7850df28cec8e0614fde437183bd4ae3e66b"
integrity sha512-pnO0I5sEQM3pmowjMGQ74adLzvc6HqGyLyqMizaGMicPu9uTYlSdId+qckYEEgPwPMaEShtv2Vg+ZHs7KVqfcg==
"@tiptap/extension-bold@^2.0.0-beta.28":
version "2.0.0-beta.28"
resolved "https://registry.yarnpkg.com/@tiptap/extension-bold/-/extension-bold-2.0.0-beta.28.tgz#cf67c264a80434ffb2368f3dd37cf357ae0c2064"
integrity sha512-DY8GOzw9xjmTFrnvTbgHUNxTnDfKrkDgrhe0SUvdkT2udntWp8umPdhPiD3vczLgHOJw6tX68qMRjbsR1ZPcHQ==
"@tiptap/extension-bubble-menu@^2.0.0-beta.56":
version "2.0.0-beta.56"
resolved "https://registry.yarnpkg.com/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.0.0-beta.56.tgz#d99cb673610a3af7e12444f4538463c7c58bfa04"
integrity sha512-nZozwauICdaNPmDPrSn1JFd/9/2rLtK8i2vBOcqxWHObVROvu8ZlJspnrJv23vS6P7/ZO3e/QLVHpnn+1yVq3g==
"@tiptap/extension-bubble-menu@^2.0.0-beta.61":
version "2.0.0-beta.61"
resolved "https://registry.yarnpkg.com/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.0.0-beta.61.tgz#cc61ce8b094fdbcec58f44f0fa39172a726c024c"
integrity sha512-T3Yx+y1sUnXAJjK1CUfsQewSxOpDca9KzKqN2H9c9RZ9UlorR9XmZg6YYW7m9a7adeihj+o3cCO9jRd8dV+nnA==
dependencies:
prosemirror-state "^1.3.4"
prosemirror-view "^1.23.6"
prosemirror-state "1.4.1"
prosemirror-view "1.26.2"
tippy.js "^6.3.7"
"@tiptap/extension-bullet-list@^2.0.0-beta.26":
version "2.0.0-beta.26"
resolved "https://registry.yarnpkg.com/@tiptap/extension-bullet-list/-/extension-bullet-list-2.0.0-beta.26.tgz#b42126d2d984c04041b14037e8d3ec1bcf16e7ec"
integrity sha512-1n5HV8gY1tLjPk4x48nva6SZlFHoPlRfF6pqSu9JcJxPO7FUSPxUokuz4swYNe0LRrtykfyNz44dUcxKVhoFow==
"@tiptap/extension-bullet-list@^2.0.0-beta.29":
version "2.0.0-beta.29"
resolved "https://registry.yarnpkg.com/@tiptap/extension-bullet-list/-/extension-bullet-list-2.0.0-beta.29.tgz#640883e4fffc1a86c7cbd78792688e7edee5ee41"
integrity sha512-R8VB2l1ZB6VeGWx/t/04nBS5Wg3qjIDEZCpPihj2fccJOw99Lu0Ub2UJg/SfdGmeNNpBh4ZYYFv1g/XjyzlXKg==
"@tiptap/extension-code-block-lowlight@2.0.0-beta.68":
version "2.0.0-beta.68"
resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block-lowlight/-/extension-code-block-lowlight-2.0.0-beta.68.tgz#c0da8c327eb2b49d808e3ead303f6ff6b0203e05"
integrity sha512-927vw4DJ5pq3lYOdJbBrCjJZ/YsbsEzWkb7SwRsaztDXcgsF2z8gt6dy7onXMaqm5rDx6eNofLPdhUyLCswW8Q==
"@tiptap/extension-code-block-lowlight@2.0.0-beta.73":
version "2.0.0-beta.73"
resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block-lowlight/-/extension-code-block-lowlight-2.0.0-beta.73.tgz#3f4711fadb1a1f51efbf58389216e6c8bca83d84"
integrity sha512-57jqDd2jzQPlYKPtnDIlwwaZrHLlgUVCe+NIWgK6bpP1yF4bUE3Dguqw1owN6oBWBf0kQnm0TQjbn50B/wnUjQ==
dependencies:
"@tiptap/extension-code-block" "^2.0.0-beta.37"
"@tiptap/extension-code-block" "^2.0.0-beta.42"
"@types/lowlight" "^0.0.3"
lowlight "^1.20.0"
prosemirror-model "^1.16.1"
prosemirror-state "^1.3.4"
prosemirror-view "^1.23.6"
prosemirror-model "1.18.1"
prosemirror-state "1.4.1"
prosemirror-view "1.26.2"
"@tiptap/extension-code-block@^2.0.0-beta.37":
version "2.0.0-beta.37"
resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block/-/extension-code-block-2.0.0-beta.37.tgz#c07c007248a21d9e0434458fd05c363b7078227f"
integrity sha512-mJAM+PHaNoKRYwM3D36lZ51/aoPxxvZNQn3UBnZ6G7l0ZJSgB3JvBEzqK6S8nNFeYIIxGwv4QF6vXe4MG9ie2g==
"@tiptap/extension-code-block@^2.0.0-beta.42":
version "2.0.0-beta.42"
resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block/-/extension-code-block-2.0.0-beta.42.tgz#2abfd92eb22399fa542aafb3b76dddfb41d87ab5"
integrity sha512-4wzLup4mI8w9ypIceekUV/8g41cQIPn31qs1iC9u1/JuTkjMj/tA+TFUyp6IMugLxoI/P2DlTztU6/6m7n9DyQ==
dependencies:
prosemirror-state "^1.3.4"
prosemirror-state "1.4.1"
"@tiptap/extension-code@^2.0.0-beta.26":
version "2.0.0-beta.26"
resolved "https://registry.yarnpkg.com/@tiptap/extension-code/-/extension-code-2.0.0-beta.26.tgz#bbfa600a252ee2cded6947b56b6c4c33d998e53a"
integrity sha512-QcFWdEFfbJ1n5UFFBD17QPPAJ3J5p/b7XV484u0shCzywO7aNPV32QeHy1z0eMoyZtCbOWf6hg/a7Ugv8IwpHw==
"@tiptap/extension-code@^2.0.0-beta.28":
version "2.0.0-beta.28"
resolved "https://registry.yarnpkg.com/@tiptap/extension-code/-/extension-code-2.0.0-beta.28.tgz#a22c0e873497ac0bbcd77e4a855322f8591f954e"
integrity sha512-QPJ2Gwb1+3NgcC1ZIhvVcb+FsnWWDu5VZXTKXM4mz892i9V2x48uHg5anPiUV6pcolXsW1F5VNbXIHGTUUO6CQ==
"@tiptap/extension-document@^2.0.0-beta.15":
version "2.0.0-beta.15"
resolved "https://registry.yarnpkg.com/@tiptap/extension-document/-/extension-document-2.0.0-beta.15.tgz#5d17a0289244a913ab2ef08e8495a1e46950711e"
integrity sha512-ypENC+xUYD5m2t+KOKNYqyXnanXd5fxyIyhR1qeEEwwQwMXGNrO3kCH6O4mIDCpy+/WqHvVay2tV5dVsXnvY8w==
"@tiptap/extension-document@^2.0.0-beta.17":
version "2.0.0-beta.17"
resolved "https://registry.yarnpkg.com/@tiptap/extension-document/-/extension-document-2.0.0-beta.17.tgz#ded4182dd860762bcf41c588f712d83908c472a3"
integrity sha512-L6sg0FNchbtIpQkCSjMmItVGs3/vep8Fq56WRtDc1wBSGUSmtHaxQG7F2FZLnNIUMuvzVMRD81m2vYG73WkY6A==
"@tiptap/extension-dropcursor@^2.0.0-beta.25":
version "2.0.0-beta.25"
resolved "https://registry.yarnpkg.com/@tiptap/extension-dropcursor/-/extension-dropcursor-2.0.0-beta.25.tgz#962f290a200259533a26194daca5a4b4a53e72d3"
integrity sha512-GYf5s6dkZtsDy+TEkrQK6kLbfbitG4qnk02D+FlhlJMI/Nnx8rYCRJbwEHDdqrfX7XwZzULMqqqHvzxZYrEeNg==
"@tiptap/extension-dropcursor@^2.0.0-beta.28":
version "2.0.0-beta.28"
resolved "https://registry.yarnpkg.com/@tiptap/extension-dropcursor/-/extension-dropcursor-2.0.0-beta.28.tgz#55013b1356fd589990003c83bb719d7b4ccad46d"
integrity sha512-t61/pALhkV7gORM+KM2M7hypNfJt+bHgk1Lk7FrWqKXQCkVGQzdOgPfnuFxpzi8kC2m7jQxvZC3S+4oBBKhkPA==
dependencies:
"@types/prosemirror-dropcursor" "^1.0.3"
prosemirror-dropcursor "^1.4.0"
prosemirror-dropcursor "^1.5.0"
"@tiptap/extension-floating-menu@^2.0.0-beta.51":
version "2.0.0-beta.51"
resolved "https://registry.yarnpkg.com/@tiptap/extension-floating-menu/-/extension-floating-menu-2.0.0-beta.51.tgz#a1e53fd1c1d2ac00025d7f094d2b62eb08e81902"
integrity sha512-rEe7jADK9xr2n2LJsrGEN3Dz7sEGC1JT/7AdTdaZBxQRQvwxTjomqYGrt+LnX+v0MYggh6swMzj7upJosnKbBg==
"@tiptap/extension-floating-menu@^2.0.0-beta.56":
version "2.0.0-beta.56"
resolved "https://registry.yarnpkg.com/@tiptap/extension-floating-menu/-/extension-floating-menu-2.0.0-beta.56.tgz#c7428d9109d215bdbd9033f69782c4aadb2aabec"
integrity sha512-j/evHE/6UPGkIgXny9IGcAh0IrcnQmg0b2NBYebs2mqx9xYKYoe+0jVgNdLp/0M3MRgQCzyWTyatBDBFOUR2mw==
dependencies:
prosemirror-state "^1.3.4"
prosemirror-view "^1.23.6"
prosemirror-state "1.4.1"
prosemirror-view "1.26.2"
tippy.js "^6.3.7"
"@tiptap/extension-gapcursor@^2.0.0-beta.34":
version "2.0.0-beta.34"
resolved "https://registry.yarnpkg.com/@tiptap/extension-gapcursor/-/extension-gapcursor-2.0.0-beta.34.tgz#0e4971affb1621934422dd5fc4bf2dd7a84f70f7"
integrity sha512-Vm8vMWWQ2kJcUOLfB5CEo5pYgyudI7JeeiZvX9ScPmUmgKVYhEpt3EAICY9pUYJ41aAVH35gZLXkUtsz2f9GHw==
dependencies:
"@types/prosemirror-gapcursor" "^1.0.4"
prosemirror-gapcursor "^1.2.1"
"@tiptap/extension-hard-break@^2.0.0-beta.30":
version "2.0.0-beta.30"
resolved "https://registry.yarnpkg.com/@tiptap/extension-hard-break/-/extension-hard-break-2.0.0-beta.30.tgz#165494f1194a7bad08907e6d64d349dd15851b72"
integrity sha512-X9xj/S+CikrbIE7ccUFVwit5QHEbflnKVxod+4zPwr1cxogFbE9AyLZE2MpYdx3z9LcnTYYi9leBqFrP4T/Olw==
"@tiptap/extension-heading@^2.0.0-beta.26":
version "2.0.0-beta.26"
resolved "https://registry.yarnpkg.com/@tiptap/extension-heading/-/extension-heading-2.0.0-beta.26.tgz#112b14b4d488772bda36abbf7cb2bc8aba7c42f5"
integrity sha512-nR6W/3rjnZH1Swo7tGBoYsmO6xMvu9MGq6jlm3WVHCB7B3CsrRvCkTwGjVIbKTaZC4bQfx5gvAUpQFvwuU+M5w==
"@tiptap/extension-history@^2.0.0-beta.21":
version "2.0.0-beta.21"
resolved "https://registry.yarnpkg.com/@tiptap/extension-history/-/extension-history-2.0.0-beta.21.tgz#5d96a17a83a7130744f0757a3275dd5b11eb1bf7"
integrity sha512-0v8Cl30V4dsabdpspLdk+f+lMoIvLFlJN5WRxtc7RRZ5gfJVxPHwooIKdvC51brfh/oJtWFCNMRjhoz0fRaF9A==
dependencies:
"@types/prosemirror-history" "^1.0.3"
prosemirror-history "^1.2.0"
"@tiptap/extension-horizontal-rule@^2.0.0-beta.31":
version "2.0.0-beta.31"
resolved "https://registry.yarnpkg.com/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.0.0-beta.31.tgz#efb383a6cedbbf4f2175d7d207eaeeba626faab0"
integrity sha512-MNc4retfjRgkv3qxqGya0+/BEd1Kmn+oMsCRvE+8x3sXyKIse+vdqMuG5qUcA6np0ZD/9hh1riiQ1GQdgc23Ng==
dependencies:
prosemirror-state "^1.3.4"
"@tiptap/extension-image@^2.0.0-beta.27":
version "2.0.0-beta.27"
resolved "https://registry.yarnpkg.com/@tiptap/extension-image/-/extension-image-2.0.0-beta.27.tgz#62152240cfa7ead03080c38485c1ebda4a603d18"
integrity sha512-kdJ7V39yNdVWUco/RBe7WgvFevd81l+pU6+Je9HpelqBBP953wDttzLMuAWQB4AeLv9WhKSlORHiFv2SKsV5NA==
"@tiptap/extension-italic@^2.0.0-beta.26":
version "2.0.0-beta.26"
resolved "https://registry.yarnpkg.com/@tiptap/extension-italic/-/extension-italic-2.0.0-beta.26.tgz#b00c9e32b81b1bd94eaed24bb2a22e44d5dc54a3"
integrity sha512-vejGe2ra4K5ipFOn1U9viqF9X9nPTX8WSJpSOux+9UbKjHpANy7bz69tp66OIi/Wh5L/MMDc+luH/04qfVnpZw==
"@tiptap/extension-link@^2.0.0-beta.38":
"@tiptap/extension-gapcursor@^2.0.0-beta.38":
version "2.0.0-beta.38"
resolved "https://registry.yarnpkg.com/@tiptap/extension-link/-/extension-link-2.0.0-beta.38.tgz#e7fb0ebee0d557ef921bf3c7fa6a7c62335f66a5"
integrity sha512-j+ygwq3cpDu5/8zPBcHyfgC5cuyO3jfV+2KcJw2I6Qi73y4Kwo3PW/leEYlSHkIt7i1zjyFHo/oDfC4K9x9eQg==
resolved "https://registry.yarnpkg.com/@tiptap/extension-gapcursor/-/extension-gapcursor-2.0.0-beta.38.tgz#14254eed2c8702a287c4952d4e83bc3baeacd759"
integrity sha512-sNMgfXLsTUew9LnjV2YTCGO0Ed6o2tkZkEQyWDoLMhdjffRPM9QUar0H+a/U+BTW8jJLwU1cRpw6uykBtWAVCw==
dependencies:
prosemirror-gapcursor "^1.3.0"
"@tiptap/extension-hard-break@^2.0.0-beta.33":
version "2.0.0-beta.33"
resolved "https://registry.yarnpkg.com/@tiptap/extension-hard-break/-/extension-hard-break-2.0.0-beta.33.tgz#e2f355a22aaaec6e831cf2880c52aa5b0b860573"
integrity sha512-41xf0vSV9hcyTFd01ItLq/CjhjgmOFLCrO3UWN/P2E/cIxuDTyXcvjTE/KXeqRCOV3OYd9fVr0wO91hc8Ij1Yg==
"@tiptap/extension-heading@^2.0.0-beta.29":
version "2.0.0-beta.29"
resolved "https://registry.yarnpkg.com/@tiptap/extension-heading/-/extension-heading-2.0.0-beta.29.tgz#d017d216c0fd1962c266f6f61a335093f9749862"
integrity sha512-q92jYcsT5bPhvuQaB0h44Z9r+Ii22tDYo082KMVnR4+tknHT/3xx+p4JC8KHjh+/5W8Quyafqy6mS8L8VX0zsQ==
"@tiptap/extension-history@^2.0.0-beta.25":
version "2.0.0-beta.25"
resolved "https://registry.yarnpkg.com/@tiptap/extension-history/-/extension-history-2.0.0-beta.25.tgz#756d8e82e8873278e567b460c67445f71563b797"
integrity sha512-G3z6BYeb742U9G2wQPhv9qzf74WxDU3h8VlD3NKl3zdqciFG/lXYH6k3+B+aKHwAWfgdYo7NtLtdWPV9EE2vCg==
dependencies:
prosemirror-history "^1.3.0"
"@tiptap/extension-horizontal-rule@^2.0.0-beta.36":
version "2.0.0-beta.36"
resolved "https://registry.yarnpkg.com/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.0.0-beta.36.tgz#daf8e2d0f30b210a90fdb8f015646653661cfa04"
integrity sha512-o+Zp7dcn3zAQhtlhZiFB69mTHuH3ZRbGEF7Cbf1D3uX1izotni5zIZbPaFFUT4r6OmVe/vDDt/nopfcGc10ktQ==
dependencies:
prosemirror-state "1.4.1"
"@tiptap/extension-image@^2.0.0-beta.30":
version "2.0.0-beta.30"
resolved "https://registry.yarnpkg.com/@tiptap/extension-image/-/extension-image-2.0.0-beta.30.tgz#60c6cfd09bfd017a3d8b1feaf0931462ffd71a60"
integrity sha512-VhEmgiKkZMiKR7hbpJgIlIUS/QNjSGI5ER7mKDAbuV1IB5yb6nGjZ6o3Exrr2/CaTaW5hQarBC1z2Xgdu05EGg==
"@tiptap/extension-italic@^2.0.0-beta.28":
version "2.0.0-beta.28"
resolved "https://registry.yarnpkg.com/@tiptap/extension-italic/-/extension-italic-2.0.0-beta.28.tgz#bf88ecae64c8f2f69f1f508b802c1efd7454a84e"
integrity sha512-/pKRiCfewh7nqiXRD3N4hQHfGrGNOiWPFYZfY35bSpvTms7PDb/MF7xT1CWW23hSpY31BBS+R/a66vlR/gqu7Q==
"@tiptap/extension-link@^2.0.0-beta.43":
version "2.0.0-beta.43"
resolved "https://registry.yarnpkg.com/@tiptap/extension-link/-/extension-link-2.0.0-beta.43.tgz#c123a2170dd50d075b9fe7fb91d86d23f778ffb0"
integrity sha512-AYueqfTW713KGVfWSWhVbj4ObeWudgawikm3m0uYcKSdsAz/CfEvOD2/NA0uyQzlxmYLA6Pf8HMxoKGN+O4Cmg==
dependencies:
linkifyjs "^3.0.5"
prosemirror-model "^1.16.1"
prosemirror-state "^1.3.4"
prosemirror-model "1.18.1"
prosemirror-state "1.4.1"
"@tiptap/extension-list-item@^2.0.0-beta.20":
version "2.0.0-beta.20"
resolved "https://registry.yarnpkg.com/@tiptap/extension-list-item/-/extension-list-item-2.0.0-beta.20.tgz#7169528b226dee4590e013bdf6e5fc6d83729b0f"
integrity sha512-5IPEspJt38t9ROj4xLUesOVEYlTT/R9Skd9meHRxJQZX1qrzBICs5PC/WRIsnexrvTBhdxpYgCYjpvpsJBlKuQ==
"@tiptap/extension-ordered-list@^2.0.0-beta.27":
version "2.0.0-beta.27"
resolved "https://registry.yarnpkg.com/@tiptap/extension-ordered-list/-/extension-ordered-list-2.0.0-beta.27.tgz#ed48a53a9b012d578613b68375db31e8664bfdc9"
integrity sha512-apFDeignxdZb3cA3p1HJu0zw1JgJdBYUBz1r7f99qdNybYuk3I/1MPUvlOuOgvIrBB/wydoyVDP+v9F7QN3tfQ==
"@tiptap/extension-paragraph@^2.0.0-beta.23":
"@tiptap/extension-list-item@^2.0.0-beta.23":
version "2.0.0-beta.23"
resolved "https://registry.yarnpkg.com/@tiptap/extension-paragraph/-/extension-paragraph-2.0.0-beta.23.tgz#2ab77308519494994d7a9e5a4acd14042f45f28c"
integrity sha512-VWAxyzecErYWk97Kv/Gkghh97zAQTcaVOisEnYYArZAlyYDaYM48qVssAC/vnRRynP2eQxb1EkppbAxE+bMHAA==
resolved "https://registry.yarnpkg.com/@tiptap/extension-list-item/-/extension-list-item-2.0.0-beta.23.tgz#6d1ac7235462b0bcee196f42bb1871669480b843"
integrity sha512-AkzvdELz3ZnrlZM0r9+ritBDOnAjXHR/8zCZhW0ZlWx4zyKPMsNG5ygivY+xr4QT65NEGRT8P8b2zOhXrMjjMQ==
"@tiptap/extension-strike@^2.0.0-beta.27":
version "2.0.0-beta.27"
resolved "https://registry.yarnpkg.com/@tiptap/extension-strike/-/extension-strike-2.0.0-beta.27.tgz#c5187bf3c28837f95a5c0c0617d0dd31c318353d"
integrity sha512-2dmCgtesuDdivM/54Q+Y6Tc3JbGz1SkHP6c62piuqBiYLWg3xa16zChZOhfN8szbbQlBgLT6XRTDt3c2Ux+Dug==
"@tiptap/extension-ordered-list@^2.0.0-beta.30":
version "2.0.0-beta.30"
resolved "https://registry.yarnpkg.com/@tiptap/extension-ordered-list/-/extension-ordered-list-2.0.0-beta.30.tgz#1f656b664302d90272c244b2e478d7056203f2a8"
integrity sha512-GRxGQdq1u0Rp5N8TjthCqoZ//460m343A0HCN7UwfQOnX7Ipv0UJemwNkSHWrl7Pexym9vy3yPWgrn7oRRmgEw==
"@tiptap/extension-subscript@^2.0.0-beta.10":
version "2.0.0-beta.10"
resolved "https://registry.yarnpkg.com/@tiptap/extension-subscript/-/extension-subscript-2.0.0-beta.10.tgz#177e9501f805d3cdcb359411b80b54dc7d77373e"
integrity sha512-er8/1lp0Rb+SKwEioW0w4oVf3EkdQZ0WS/5kPBG4W0DncfUMT+bw5de76S3kRL9PLZ9UShAL7wuXtuiSi5QsMw==
"@tiptap/extension-superscript@^2.0.0-beta.10":
version "2.0.0-beta.10"
resolved "https://registry.yarnpkg.com/@tiptap/extension-superscript/-/extension-superscript-2.0.0-beta.10.tgz#f91c19c2d30aabe3f8c21e87f8e5e8b2e6a55893"
integrity sha512-TUUBS8XsD2MorGORYVlhGDH7wcc9diSbHscD4Dnz8pKWVR0JPUd/od4h5qSffDzAOKxtphTiX9LOFWk6zVooKg==
"@tiptap/extension-table-cell@^2.0.0-beta.20":
version "2.0.0-beta.20"
resolved "https://registry.yarnpkg.com/@tiptap/extension-table-cell/-/extension-table-cell-2.0.0-beta.20.tgz#859456fe8d7276a87161006a3f9b3642b306524c"
integrity sha512-IllQyxLQvgm1FAewz3U+DkgNHRthmuVrtUQnG6la45qdUOLCOrpFbRRaQ1LJ/BpbvZ2Xs1o2yAa97BqZOPwovQ==
"@tiptap/extension-table-header@^2.0.0-beta.22":
version "2.0.0-beta.22"
resolved "https://registry.yarnpkg.com/@tiptap/extension-table-header/-/extension-table-header-2.0.0-beta.22.tgz#a1672970d8985c383411bb21c18e71fc7e53e262"
integrity sha512-nMrghrfl+ZS4EDixs3lgXnHw1Q+ECyTugpRvS36rP7b8GFp3GXm9DfbIAUzwGGfcq1D7DwRnJUDM6ARdWXyw0w==
"@tiptap/extension-table-row@^2.0.0-beta.19":
version "2.0.0-beta.19"
resolved "https://registry.yarnpkg.com/@tiptap/extension-table-row/-/extension-table-row-2.0.0-beta.19.tgz#b45e82f29dfcc7405440ba237b069dbb93d1a94a"
integrity sha512-ldEVDpIUX7ZqbViTy4c/RfyNGRv++O/r3A/Ivuon1PykaDDTbPlp5JM89FunAD39cLAbo2HKtweqdmzCMlZsqA==
"@tiptap/extension-table@^2.0.0-beta.49":
version "2.0.0-beta.49"
resolved "https://registry.yarnpkg.com/@tiptap/extension-table/-/extension-table-2.0.0-beta.49.tgz#10e2fbc204290ae39b6768c9247f6aaced666776"
integrity sha512-7irrvMUe9z/6Y8DcFwSuxaIVQ71VUUT1xxv6NZADvdf0HJWesCaTpVORISTnNuQdO5nwEyJXXJ5Ri/82YzWe0g==
dependencies:
"@types/prosemirror-model" "^1.16.0"
"@types/prosemirror-state" "^1.2.8"
prosemirror-model "^1.16.1"
prosemirror-state "^1.3.4"
prosemirror-tables "^1.1.1"
prosemirror-view "^1.23.6"
"@tiptap/extension-task-item@^2.0.0-beta.32":
version "2.0.0-beta.32"
resolved "https://registry.yarnpkg.com/@tiptap/extension-task-item/-/extension-task-item-2.0.0-beta.32.tgz#590efcf36143cf0afd0bbd7bc1d55bfb91025bf4"
integrity sha512-ogeZHDUBNZtlcV6on+I6zenlvsXHzjFcgQIVedK+o4h8icnURFf5m4D3m1hMuM8UGj1pIu4atFDDvAAVi7RLew==
"@tiptap/extension-task-list@^2.0.0-beta.26":
"@tiptap/extension-paragraph@^2.0.0-beta.26":
version "2.0.0-beta.26"
resolved "https://registry.yarnpkg.com/@tiptap/extension-task-list/-/extension-task-list-2.0.0-beta.26.tgz#75a20795429c40c3b12544483ea63014487d71c7"
integrity sha512-7zPpz9eOUCnFyWNDFYPCUJ39gjID+mCI5BuXyXrjJjDfm8wxg/xTgg9+KC6xakczos7DypnhzlRKSs4EFczeUg==
resolved "https://registry.yarnpkg.com/@tiptap/extension-paragraph/-/extension-paragraph-2.0.0-beta.26.tgz#5199c8cedb9c076347a2e15cc67442ef7c3c3fbb"
integrity sha512-WcYsuUa7LLfk0vi7I1dVjdMRu53B52FMMqd+UL1qPdDKVkU3DBsZVwPj+yyfQyqN8Mc/xyg9VacGaiKFLmWNDg==
"@tiptap/extension-text@^2.0.0-beta.15":
version "2.0.0-beta.15"
resolved "https://registry.yarnpkg.com/@tiptap/extension-text/-/extension-text-2.0.0-beta.15.tgz#f08cff1b78f1c6996464dfba1fef8ec1e107617f"
integrity sha512-S3j2+HyV2gsXZP8Wg/HA+YVXQsZ3nrXgBM9HmGAxB0ESOO50l7LWfip0f3qcw1oRlh5H3iLPkA6/f7clD2/TFA==
"@tiptap/extension-strike@^2.0.0-beta.29":
version "2.0.0-beta.29"
resolved "https://registry.yarnpkg.com/@tiptap/extension-strike/-/extension-strike-2.0.0-beta.29.tgz#7004d0c5d126b0517fa78efc5a333a4b8e3334bf"
integrity sha512-zqFuY7GfNmZ/KClt6kxQ+msGo3syqucP/Xnlihxi+/h/G+oTvEwyOIXCtDOltvxcsWH/TUsdr5vzLp0j+Mdc6Q==
"@tiptap/vue-2@^2.0.0-beta.79":
version "2.0.0-beta.79"
resolved "https://registry.yarnpkg.com/@tiptap/vue-2/-/vue-2-2.0.0-beta.79.tgz#8192fc56b083097559f8158a177f76572ecfabf1"
integrity sha512-dwprmBVRvPJl0gMgH6LBU79yqhTbjiDQ3ReNtZ+MFBqwujQfkAqnsm6VVgLjd4jHsV+nzblP5HPH8s9MhIdySw==
"@tiptap/extension-subscript@^2.0.0-beta.13":
version "2.0.0-beta.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-subscript/-/extension-subscript-2.0.0-beta.13.tgz#5da9523b50240c4f4999b1941d5d66d6ca85189d"
integrity sha512-L9f2zKzNI5y4YvMdNxHDT4Y+8gS1UwtbTJ1vUJdCZGfF8DrMuTZIRp3LjOxYXydr7NGEXyYbucdm97Tzrsp8WA==
"@tiptap/extension-superscript@^2.0.0-beta.13":
version "2.0.0-beta.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-superscript/-/extension-superscript-2.0.0-beta.13.tgz#053b7df90ea26451c020075424b78053325672c1"
integrity sha512-Vr9KIG2c4jzymcMMQCjhx2gppmRvnbw6Xvrd8YCpK4szyYI1ClMQ5KQMYl2zV3Y4ZIsivRSy9cE0ipGsXGE3Gw==
"@tiptap/extension-table-cell@^2.0.0-beta.23":
version "2.0.0-beta.23"
resolved "https://registry.yarnpkg.com/@tiptap/extension-table-cell/-/extension-table-cell-2.0.0-beta.23.tgz#a460318be151434ac31daffe94c2c4e53f2ea229"
integrity sha512-LTvmAXkbwpLlGhwvVJabOKJbrWZYRp+0DizJaFtBXLSAHqzW9FQjuUhkTokeDRSc+PHMOb0tE1Kz6CRd8onIkA==
"@tiptap/extension-table-header@^2.0.0-beta.25":
version "2.0.0-beta.25"
resolved "https://registry.yarnpkg.com/@tiptap/extension-table-header/-/extension-table-header-2.0.0-beta.25.tgz#65e16d2a12973c60b837de100a5ac88be1da7372"
integrity sha512-MO9Fa4Ng2sSBAov8cBJR3CxUBSaQQhNY6Dq2h3JINWUs03GPN3iihiVtD5N+0SFs8O4xJ5B8Cifkvd72lSqI3w==
"@tiptap/extension-table-row@^2.0.0-beta.22":
version "2.0.0-beta.22"
resolved "https://registry.yarnpkg.com/@tiptap/extension-table-row/-/extension-table-row-2.0.0-beta.22.tgz#a113ca3cde46af1fe7ecc4c229770726aedfd342"
integrity sha512-o47oQn3Sv27iIinBf1s1nHoiFLdujNtSkfHhUgUz8zeyXRT2PtKmwSSEglB3c5jGAmt1CLfU8QJrmrV38CwFYw==
"@tiptap/extension-table@^2.0.0-beta.54":
version "2.0.0-beta.54"
resolved "https://registry.yarnpkg.com/@tiptap/extension-table/-/extension-table-2.0.0-beta.54.tgz#d0590fb1634bbad34fe407018c9c4de1388803d3"
integrity sha512-KZbocjS9EbWMr/z7U8CUnVhMlV/YEDi7nV1lmrfzmQ6CVIJFQ9FrWCztN1QH3hWnvIcRnR6GM+5VdjFlalsp3A==
dependencies:
"@tiptap/extension-bubble-menu" "^2.0.0-beta.56"
"@tiptap/extension-floating-menu" "^2.0.0-beta.51"
prosemirror-view "^1.23.6"
"@_ueberdosis/prosemirror-tables" "1.1.3"
prosemirror-model "1.18.1"
prosemirror-state "1.4.1"
prosemirror-view "1.26.2"
"@tiptap/extension-task-item@^2.0.0-beta.37":
version "2.0.0-beta.37"
resolved "https://registry.yarnpkg.com/@tiptap/extension-task-item/-/extension-task-item-2.0.0-beta.37.tgz#fcf719c4f6d09a69a6525f116bb96560bddfdf51"
integrity sha512-zdTE7G6KHgdr+V32eWk7V6YkKxV3X0VJvfuybRlUcS4QyX4dSWnIqeHzzmX8Jd9IXjRghIFtjNi7IKxIGAhMsg==
"@tiptap/extension-task-list@^2.0.0-beta.29":
version "2.0.0-beta.29"
resolved "https://registry.yarnpkg.com/@tiptap/extension-task-list/-/extension-task-list-2.0.0-beta.29.tgz#3ca388b9251e4d42d152177c609f6cebb57c4a1e"
integrity sha512-PbHlVmYWevClA3mmXyshhR58GT1J22vVlFEDj2o25WRPY2dCTv4X136wPRVf9ee4nZII0Xcp2SsVC1kfgtuVRg==
"@tiptap/extension-text@^2.0.0-beta.17":
version "2.0.0-beta.17"
resolved "https://registry.yarnpkg.com/@tiptap/extension-text/-/extension-text-2.0.0-beta.17.tgz#4fdd1bdf62c82c1af6feef91c689906a8f5b171e"
integrity sha512-OyKL+pqWJEtjyd9/mrsuY1kZh2b3LWpOQDWKtd4aWR4EA0efmQG+7FPwcIeAVEh7ZoqM+/ABCnPjN6IjzIrSfg==
"@tiptap/vue-2@^2.0.0-beta.84":
version "2.0.0-beta.84"
resolved "https://registry.yarnpkg.com/@tiptap/vue-2/-/vue-2-2.0.0-beta.84.tgz#abf2e8e53759e9d7c69b6a7f62164a1a8be2c013"
integrity sha512-LJGVqD69pQn+8ZxYpROcRG4Zv2eAK7mFsKGf/tywtews09OkEynLbwyAePsF1nxsUASiA8M7rEiWoKWGFtJ6Qg==
dependencies:
"@tiptap/extension-bubble-menu" "^2.0.0-beta.61"
"@tiptap/extension-floating-menu" "^2.0.0-beta.56"
prosemirror-view "1.26.2"
"@tootallnate/once@1":
version "1.1.2"
@ -2080,11 +2078,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/orderedmap@*":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@types/orderedmap/-/orderedmap-1.0.0.tgz#807455a192bba52cbbb4517044bc82bdbfa8c596"
integrity sha512-dxKo80TqYx3YtBipHwA/SdFmMMyLCnP+5mkEqN0eMjcTBzHkiiX0ES118DsjDBjvD+zeSsSU9jULTZ+frog+Gw==
"@types/parse-json@^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
@ -2105,89 +2098,6 @@
resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.0.2.tgz#5bb52ee68d0f8efa9cc0099920e56be6cc4e37f3"
integrity sha512-IkVfat549ggtkZUthUzEX49562eGikhSYeVGX97SkMFn+sTZrgRewXjQ4tPKFPCykZHkX1Zfd9OoELGqKU2jJA==
"@types/prosemirror-commands@*", "@types/prosemirror-commands@^1.0.4":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@types/prosemirror-commands/-/prosemirror-commands-1.0.4.tgz#d08551415127d93ae62e7239d30db0b5e7208e22"
integrity sha512-utDNYB3EXLjAfYIcRWJe6pn3kcQ5kG4RijbT/0Y/TFOm6yhvYS/D9eJVnijdg9LDjykapcezchxGRqFD5LcyaQ==
dependencies:
"@types/prosemirror-model" "*"
"@types/prosemirror-state" "*"
"@types/prosemirror-view" "*"
"@types/prosemirror-dropcursor@^1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@types/prosemirror-dropcursor/-/prosemirror-dropcursor-1.0.3.tgz#49250849b8a0b86e8c29eb1ba70a463e53e46947"
integrity sha512-b0/8njnJ4lwyHKcGuCMf3x7r1KjxyugB1R/c2iMCjplsJHSC7UY9+OysqgJR5uUXRekUSGniiLgBtac/lvH6wg==
dependencies:
"@types/prosemirror-state" "*"
"@types/prosemirror-gapcursor@^1.0.4":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@types/prosemirror-gapcursor/-/prosemirror-gapcursor-1.0.4.tgz#7df7d373edb33ea8da12084bfd462cf84cd69761"
integrity sha512-9xKjFIG5947dzerFvkLWp6F53JwrUYoYwh3SgcTFEp8SbSfNNrez/PFYVZKPnoqPoaK5WtTdQTaMwpCV9rXQIg==
dependencies:
"@types/prosemirror-model" "*"
"@types/prosemirror-state" "*"
"@types/prosemirror-history@^1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@types/prosemirror-history/-/prosemirror-history-1.0.3.tgz#f1110efbe758129b5475e466ff077f0a8d9b964f"
integrity sha512-5TloMDRavgLjOAKXp1Li8u0xcsspzbT1Cm9F2pwHOkgvQOz1jWQb2VIXO7RVNsFjLBZdIXlyfSLivro3DuMWXg==
dependencies:
"@types/prosemirror-model" "*"
"@types/prosemirror-state" "*"
"@types/prosemirror-keymap@^1.0.4":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@types/prosemirror-keymap/-/prosemirror-keymap-1.0.4.tgz#f73c79810e8d0e0a20d153d84f998f02e5afbc0c"
integrity sha512-ycevwkqUh+jEQtPwqO7sWGcm+Sybmhu8MpBsM8DlO3+YTKnXbKA6SDz/+q14q1wK3UA8lHJyfR+v+GPxfUSemg==
dependencies:
"@types/prosemirror-commands" "*"
"@types/prosemirror-model" "*"
"@types/prosemirror-state" "*"
"@types/prosemirror-view" "*"
"@types/prosemirror-model@*", "@types/prosemirror-model@^1.16.0":
version "1.16.0"
resolved "https://registry.yarnpkg.com/@types/prosemirror-model/-/prosemirror-model-1.16.0.tgz#8b22c7431a4c93f7f550fc89c4b0e2d44d42c8b6"
integrity sha512-nv93YLyTEcDDl17OB90EldxZjyJQJll2WSMLDvLzTewbpvE/vtMjHT3j4mik3uSzQ6YD486AcloCO3WODY/lDg==
dependencies:
"@types/orderedmap" "*"
"@types/prosemirror-schema-list@^1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@types/prosemirror-schema-list/-/prosemirror-schema-list-1.0.3.tgz#bdf1893a7915fbdc5c49b3cac9368e96213d70de"
integrity sha512-uWybOf+M2Ea7rlbs0yLsS4YJYNGXYtn4N+w8HCw3Vvfl6wBAROzlMt0gV/D/VW/7J/LlAjwMezuGe8xi24HzXA==
dependencies:
"@types/orderedmap" "*"
"@types/prosemirror-model" "*"
"@types/prosemirror-state" "*"
"@types/prosemirror-state@*", "@types/prosemirror-state@^1.2.8":
version "1.2.8"
resolved "https://registry.yarnpkg.com/@types/prosemirror-state/-/prosemirror-state-1.2.8.tgz#65080eeec52f63c50bf7034377f07773b4f6b2ac"
integrity sha512-mq9uyQWcpu8jeamO6Callrdvf/e1H/aRLR2kZWSpZrPHctEsxWHBbluD/wqVjXBRIOoMHLf6ZvOkrkmGLoCHVA==
dependencies:
"@types/prosemirror-model" "*"
"@types/prosemirror-transform" "*"
"@types/prosemirror-view" "*"
"@types/prosemirror-transform@*", "@types/prosemirror-transform@^1.1.5":
version "1.1.5"
resolved "https://registry.yarnpkg.com/@types/prosemirror-transform/-/prosemirror-transform-1.1.5.tgz#e6949398c64a5d3ca53e6081352751aa9e9ce76e"
integrity sha512-Wr2HXaEF4JPklWpC17RTxE6PxyU54Taqk5FMhK1ojgcN93J+GpkYW8s0mD3rl7KfTmlhVwZPCHE9o0cYf2Go5A==
dependencies:
"@types/prosemirror-model" "*"
"@types/prosemirror-view@*", "@types/prosemirror-view@^1.23.1":
version "1.23.1"
resolved "https://registry.yarnpkg.com/@types/prosemirror-view/-/prosemirror-view-1.23.1.tgz#a9a926bb6b6e6873e3a9d8caa61c32f3402629eb"
integrity sha512-6e1B2oKUnhmZPUrsVvYjDqeVjE6jGezygjtoHsAK4ZENAxHzHqy5NT4jUvdPTWjCYeH0t2Y7pSfRPNrPIyQX4A==
dependencies:
"@types/prosemirror-model" "*"
"@types/prosemirror-state" "*"
"@types/prosemirror-transform" "*"
"@types/qs@*":
version "6.9.7"
resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb"
@ -5104,6 +5014,11 @@ entities@^2.0.0, entities@~2.1.0:
resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5"
integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==
entities@~3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4"
integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==
envinfo@^7.7.3:
version "7.8.1"
resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475"
@ -5767,13 +5682,6 @@ fastq@^1.6.0:
dependencies:
reusify "^1.0.4"
fault@^1.0.0:
version "1.0.4"
resolved "https://registry.yarnpkg.com/fault/-/fault-1.0.4.tgz#eafcfc0a6d214fc94601e170df29954a4f842f13"
integrity sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==
dependencies:
format "^0.2.0"
fault@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/fault/-/fault-2.0.1.tgz#d47ca9f37ca26e4bd38374a7c500b5a384755b6c"
@ -6490,11 +6398,6 @@ highlight.js@^11.5.1, highlight.js@~11.5.0:
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.5.1.tgz#027c24e4509e2f4dcd00b4a6dda542ce0a1f7aea"
integrity sha512-LKzHqnxr4CrD2YsNoIf/o5nJ09j4yi/GcH5BnYz9UnVpZdS4ucMgvP61TDty5xJcFGRjnH4DpujkS9bHT3hq0Q==
highlight.js@~10.7.0:
version "10.7.2"
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.2.tgz#89319b861edc66c48854ed1e6da21ea89f847360"
integrity sha512-oFLl873u4usRM9K63j4ME9u3etNF0PLiJhSQ8rdfuL51Wn3zkD6drf9ZW0dOzjnZI22YYG24z30JcmfCZjMgYg==
hmac-drbg@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
@ -7919,6 +7822,13 @@ linkify-it@^3.0.1:
dependencies:
uc.micro "^1.0.1"
linkify-it@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-4.0.1.tgz#01f1d5e508190d06669982ba31a7d9f56a5751ec"
integrity sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==
dependencies:
uc.micro "^1.0.1"
linkifyjs@^3.0.5:
version "3.0.5"
resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-3.0.5.tgz#99e51a3a0c0e232fcb63ebb89eea3ff923378f34"
@ -8122,14 +8032,6 @@ loose-envify@^1.4.0:
dependencies:
js-tokens "^3.0.0 || ^4.0.0"
lowlight@^1.20.0:
version "1.20.0"
resolved "https://registry.yarnpkg.com/lowlight/-/lowlight-1.20.0.tgz#ddb197d33462ad0d93bf19d17b6c301aa3941888"
integrity sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==
dependencies:
fault "^1.0.0"
highlight.js "~10.7.0"
lowlight@^2.6.1:
version "2.6.1"
resolved "https://registry.yarnpkg.com/lowlight/-/lowlight-2.6.1.tgz#d3cbc7ae0530c848e512b8e6528609587520b44f"
@ -8215,7 +8117,7 @@ map-visit@^1.0.0:
dependencies:
object-visit "^1.0.0"
markdown-it@12.3.2, markdown-it@^12.0.0:
markdown-it@12.3.2:
version "12.3.2"
resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-12.3.2.tgz#bf92ac92283fe983fe4de8ff8abfb5ad72cd0c90"
integrity sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==
@ -8226,6 +8128,17 @@ markdown-it@12.3.2, markdown-it@^12.0.0:
mdurl "^1.0.1"
uc.micro "^1.0.5"
markdown-it@^13.0.1:
version "13.0.1"
resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-13.0.1.tgz#c6ecc431cacf1a5da531423fc6a42807814af430"
integrity sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==
dependencies:
argparse "^2.0.1"
entities "~3.0.1"
linkify-it "^4.0.1"
mdurl "^1.0.1"
uc.micro "^1.0.5"
markdown-table@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-3.0.2.tgz#9b59eb2c1b22fe71954a65ff512887065a7bb57c"
@ -9455,10 +9368,10 @@ optionator@^0.9.1:
type-check "^0.4.0"
word-wrap "^1.2.3"
orderedmap@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/orderedmap/-/orderedmap-1.1.1.tgz#c618e77611b3b21d0fe3edc92586265e0059c789"
integrity sha512-3Ux8um0zXbVacKUkcytc0u3HgC0b0bBLT+I60r2J/En72cI0nZffqrA7Xtf2Hqs27j1g82llR5Mhbd0Z1XW4AQ==
orderedmap@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/orderedmap/-/orderedmap-2.0.0.tgz#12ff5ef6ea9d12d6430b80c701b35475e1c9ff34"
integrity sha512-buf4PoAMlh45b8a8gsGy/X6w279TSqkyAS0C0wdTSJwFSU+ljQFJON5I8NfjLHoCXwpSROIo2wr0g33T+kQshQ==
os-browserify@^0.3.0:
version "0.3.0"
@ -9987,120 +9900,110 @@ 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-commands@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/prosemirror-commands/-/prosemirror-commands-1.2.1.tgz#eae0cb714df695260659b78ff5d201d3a037e50d"
integrity sha512-S/IkpXfpuLFsRynC2HQ5iYROUPiZskKS1+ClcWycGJvj4HMb/mVfeEkQrixYxgTl96EAh+RZQNWPC06GZXk5tQ==
prosemirror-commands@1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/prosemirror-commands/-/prosemirror-commands-1.3.0.tgz#361b2e2b2a347ce7453386459f97c3f549a1113b"
integrity sha512-BwBbZ5OAScPcm0x7H8SPbqjuEJnCU2RJT9LDyOiiIl/3NbL1nJZI4SFNHwU2e/tRr2Xe7JsptpzseqvZvToLBQ==
dependencies:
prosemirror-model "^1.0.0"
prosemirror-state "^1.0.0"
prosemirror-transform "^1.0.0"
prosemirror-dropcursor@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/prosemirror-dropcursor/-/prosemirror-dropcursor-1.4.0.tgz#91a859d4ee79c99b1c0ba6ee61c093b195c0d9f0"
integrity sha512-6+YwTjmqDwlA/Dm+5wK67ezgqgjA/MhSDgaNxKUzH97SmeuWFXyLeDRxxOPZeSo7yTxcDGUCWTEjmQZsVBuMrQ==
prosemirror-dropcursor@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/prosemirror-dropcursor/-/prosemirror-dropcursor-1.5.0.tgz#edbc61d6f71f9f924130eec8e85b0861357957c9"
integrity sha512-vy7i77ddKyXlu8kKBB3nlxLBnsWyKUmQIPB5x8RkYNh01QNp/qqGmdd5yZefJs0s3rtv5r7Izfu2qbtr+tYAMQ==
dependencies:
prosemirror-state "^1.0.0"
prosemirror-transform "^1.1.0"
prosemirror-view "^1.1.0"
prosemirror-gapcursor@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/prosemirror-gapcursor/-/prosemirror-gapcursor-1.2.1.tgz#02365e1bcc1ad25d390b0fb7f0e94a7fc173ad75"
integrity sha512-PHa9lj27iM/g4C46gxVzsefuXVfy/LrGQH4QjMRht7VDBgw77iWYWn8ZHMWSFkwtr9jQEuxI5gccHHHwWG80nw==
prosemirror-gapcursor@^1.3.0:
version "1.3.1"
resolved "https://registry.yarnpkg.com/prosemirror-gapcursor/-/prosemirror-gapcursor-1.3.1.tgz#8cfd874592e4504d63720e14ed680c7866e64554"
integrity sha512-GKTeE7ZoMsx5uVfc51/ouwMFPq0o8YrZ7Hx4jTF4EeGbXxBveUV8CGv46mSHuBBeXGmvu50guoV2kSnOeZZnUA==
dependencies:
prosemirror-keymap "^1.0.0"
prosemirror-model "^1.0.0"
prosemirror-state "^1.0.0"
prosemirror-view "^1.0.0"
prosemirror-history@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/prosemirror-history/-/prosemirror-history-1.2.0.tgz#04cc4df8d2f7b2a46651a2780de191ada6d465ea"
integrity sha512-B9v9xtf4fYbKxQwIr+3wtTDNLDZcmMMmGiI3TAPShnUzvo+Rmv1GiUrsQChY1meetHl7rhML2cppF3FTs7f7UQ==
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==
dependencies:
prosemirror-state "^1.2.2"
prosemirror-transform "^1.0.0"
rope-sequence "^1.3.0"
prosemirror-keymap@^1.0.0, prosemirror-keymap@^1.1.2, prosemirror-keymap@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/prosemirror-keymap/-/prosemirror-keymap-1.1.5.tgz#b5984c7d30f5c75956c853126c54e9e624c0327b"
integrity sha512-8SZgPH3K+GLsHL2wKuwBD9rxhsbnVBTwpHCO4VUO5GmqUQlxd/2GtBVWTsyLq4Dp3N9nGgPd3+lZFKUDuVp+Vw==
prosemirror-keymap@1.2.0, prosemirror-keymap@^1.0.0, prosemirror-keymap@^1.1.2:
version "1.2.0"
resolved "https://registry.yarnpkg.com/prosemirror-keymap/-/prosemirror-keymap-1.2.0.tgz#d5cc9da9b712020690a994b50b92a0e448a60bf5"
integrity sha512-TdSfu+YyLDd54ufN/ZeD1VtBRYpgZnTPnnbY+4R08DDgs84KrIPEPbJL8t1Lm2dkljFx6xeBE26YWH3aIzkPKg==
dependencies:
prosemirror-state "^1.0.0"
w3c-keyname "^2.2.0"
prosemirror-markdown@1.8.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/prosemirror-markdown/-/prosemirror-markdown-1.8.0.tgz#4ae430470f9e433d6fb9d1e981842d7e4f664f69"
integrity sha512-RxGyM8dqdmlkYpM3PY/C5JBputv2xeKLNRqFpN04TtFlR9McN9Tmpf8DaP6HblfaZ8RofdUtQW+ghdArjANLvQ==
prosemirror-markdown@1.9.1:
version "1.9.1"
resolved "https://registry.yarnpkg.com/prosemirror-markdown/-/prosemirror-markdown-1.9.1.tgz#37d58cf7ccc5d0771b2be1fd41bc46e9daed9a94"
integrity sha512-qvCvkbpeXFoohB5M0/cfQuDRB2uh5yw7OMterDE4xvwCAbEMiaCzCzgrzm5DOehYrHkaTiybDw+DZBqGTE/kRA==
dependencies:
markdown-it "^12.0.0"
markdown-it "^13.0.1"
prosemirror-model "^1.0.0"
prosemirror-model@^1.0.0, prosemirror-model@^1.16.0, prosemirror-model@^1.16.1, prosemirror-model@^1.2.0, prosemirror-model@^1.8.1:
version "1.16.1"
resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.16.1.tgz#fb388270bc9609b66298d6a7e15d0cc1d6c61253"
integrity sha512-r1/w0HDU40TtkXp0DyKBnFPYwd8FSlUSJmGCGFv4DeynfeSlyQF2FD0RQbVEMOe6P3PpUSXM6LZBV7W/YNZ4mA==
prosemirror-model@1.18.1, prosemirror-model@^1.0.0, prosemirror-model@^1.16.0, prosemirror-model@^1.18.1, prosemirror-model@^1.2.0, prosemirror-model@^1.8.1:
version "1.18.1"
resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.18.1.tgz#1d5d6b6de7b983ee67a479dc607165fdef3935bd"
integrity sha512-IxSVBKAEMjD7s3n8cgtwMlxAXZrC7Mlag7zYsAKDndAqnDScvSmp/UdnRTV/B33lTCVU3CCm7dyAn/rVVD0mcw==
dependencies:
orderedmap "^1.1.0"
orderedmap "^2.0.0"
prosemirror-schema-basic@^1.0.0, prosemirror-schema-basic@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/prosemirror-schema-basic/-/prosemirror-schema-basic-1.1.2.tgz#4bde5c339c845e0d08ec8fe473064e372ca51ae3"
integrity sha512-G4q8WflNsR1Q33QAV4MQO0xWrHLOJ+BQcKswGXMy626wlQj6c/1n1v4eC9ns+h2y1r/fJHZEgSZnsNhm9lbrDw==
prosemirror-schema-basic@^1.0.0, prosemirror-schema-basic@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/prosemirror-schema-basic/-/prosemirror-schema-basic-1.2.0.tgz#c33ad74426efae1d41e2260371866f623e8eb10e"
integrity sha512-JMN/ammP94ObOUS6cpIy121r0MEDN9V95mAxFVALwC4bbmhpWXGjBGHTA5LHPPdbqZKyR6Jar1Akv4Z5k9CNLw==
dependencies:
prosemirror-model "^1.2.0"
prosemirror-schema-list@^1.0.0, prosemirror-schema-list@^1.1.6:
version "1.1.6"
resolved "https://registry.yarnpkg.com/prosemirror-schema-list/-/prosemirror-schema-list-1.1.6.tgz#c3e13fe2f74750e4a53ff88d798dc0c4ccca6707"
integrity sha512-aFGEdaCWmJzouZ8DwedmvSsL50JpRkqhQ6tcpThwJONVVmCgI36LJHtoQ4VGZbusMavaBhXXr33zyD2IVsTlkw==
prosemirror-schema-list@1.2.0, prosemirror-schema-list@^1.0.0, prosemirror-schema-list@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/prosemirror-schema-list/-/prosemirror-schema-list-1.2.0.tgz#1932268593a7396c0ac168cbe31f28187406ce24"
integrity sha512-8PT/9xOx1HHdC7fDNNfhQ50Z8Mzu7nKyA1KCDltSpcZVZIbB0k7KtsHrnXyuIhbLlScoymBiLZ00c5MH6wdFsA==
dependencies:
prosemirror-model "^1.0.0"
prosemirror-state "^1.0.0"
prosemirror-transform "^1.0.0"
prosemirror-state@1.4.1, prosemirror-state@^1.0.0, prosemirror-state@^1.2.2, prosemirror-state@^1.3.1, prosemirror-state@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/prosemirror-state/-/prosemirror-state-1.4.1.tgz#f6e26c7b6a7e11206176689eb6ebbf91870953e1"
integrity sha512-U/LBDW2gNmVa07sz/D229XigSdDQ5CLFwVB1Vb32MJbAHHhWe/6pOc721faI17tqw4pZ49i1xfY/jEZ9tbIhPg==
dependencies:
prosemirror-model "^1.0.0"
prosemirror-transform "^1.0.0"
prosemirror-state@^1.0.0, prosemirror-state@^1.2.2, prosemirror-state@^1.3.1, prosemirror-state@^1.3.4:
version "1.3.4"
resolved "https://registry.yarnpkg.com/prosemirror-state/-/prosemirror-state-1.3.4.tgz#4c6b52628216e753fc901c6d2bfd84ce109e8952"
integrity sha512-Xkkrpd1y/TQ6HKzN3agsQIGRcLckUMA9u3j207L04mt8ToRgpGeyhbVv0HI7omDORIBHjR29b7AwlATFFf2GLA==
dependencies:
prosemirror-model "^1.0.0"
prosemirror-transform "^1.0.0"
prosemirror-tables@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/prosemirror-tables/-/prosemirror-tables-1.1.1.tgz#ad66300cc49500455cf1243bb129c9e7d883321e"
integrity sha512-LmCz4jrlqQZRsYRDzCRYf/pQ5CUcSOyqZlAj5kv67ZWBH1SVLP2U9WJEvQfimWgeRlIz0y0PQVqO1arRm1+woA==
dependencies:
prosemirror-keymap "^1.1.2"
prosemirror-model "^1.8.1"
prosemirror-state "^1.3.1"
prosemirror-transform "^1.2.1"
prosemirror-view "^1.13.3"
prosemirror-test-builder@^1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/prosemirror-test-builder/-/prosemirror-test-builder-1.0.6.tgz#5b3df044beee6050791e96abc80fb48e66be30ea"
integrity sha512-71pbSJqaqUJfbLwGett1yhMRQ/TV7QcOPfHvj6X9U/u/nQeZQNnsHsaVBpUeLgICADtusQSVPvyeGC0LGknwgA==
prosemirror-test-builder@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/prosemirror-test-builder/-/prosemirror-test-builder-1.1.0.tgz#70d0b10d56e45dff47e0e4b0a1b29c4403a5d9e6"
integrity sha512-8fHiArJ5U3GyIjEriC02d9AcfFVYRKOarlV2aehdN5qEVO0YFFPCHoeaFeneInA29ubHycNQua7HqgykWHqr+w==
dependencies:
prosemirror-model "^1.0.0"
prosemirror-schema-basic "^1.0.0"
prosemirror-schema-list "^1.0.0"
prosemirror-transform@^1.0.0, prosemirror-transform@^1.1.0, prosemirror-transform@^1.2.1, prosemirror-transform@^1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/prosemirror-transform/-/prosemirror-transform-1.3.3.tgz#5f6712b0577a119cc418686fe7588b6dd9b7464d"
integrity sha512-9NLVXy1Sfa2G6qPqhWMkEvwQQMTw7OyTqOZbJaGQWsCeH3hH5Cw+c5eNaLM1Uu75EyKLsEZhJ93XpHJBa6RX8A==
prosemirror-transform@1.6.0, prosemirror-transform@^1.0.0, prosemirror-transform@^1.1.0, prosemirror-transform@^1.2.1:
version "1.6.0"
resolved "https://registry.yarnpkg.com/prosemirror-transform/-/prosemirror-transform-1.6.0.tgz#8162dbfaf124f9253a7ab28605a9460411a96a53"
integrity sha512-MAp7AjsjEGEqQY0sSMufNIUuEyB1ZR9Fqlm8dTwwWwpEJRv/plsKjWXBbx52q3Ml8MtaMcd7ic14zAHVB3WaMw==
dependencies:
prosemirror-model "^1.0.0"
prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3, prosemirror-view@^1.23.13, prosemirror-view@^1.23.6:
version "1.23.13"
resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.23.13.tgz#d423c601d33ad3adfd1ab73fb72270acc9de9adf"
integrity sha512-X/NcwZv8pgcEWfs3n++Wz4nDgqDIeDvJ9kfCk6DCoC9XUlDekqJLFt9wCcCUBXedb8hs/dmd+JmcaLgbr67XZw==
prosemirror-view@1.26.2, prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3, prosemirror-view@^1.26.1:
version "1.26.2"
resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.26.2.tgz#e673894ecf26aea330b727622d561c51b41d31eb"
integrity sha512-CGKw+GadkfSBEwRAJTHCEKJ4DlV6/3IhAdjpwGyZHUHtbP7jX4Ol4zmi7xa2c6GOabDlIJLYXJydoNYLX7lNeQ==
dependencies:
prosemirror-model "^1.16.0"
prosemirror-state "^1.0.0"