Merge branch 'feat/list-autojoins' into chore/page-transactions

This commit is contained in:
Palanikannan1437 2024-03-27 17:07:49 +05:30
commit 51af9e4d12
21 changed files with 2147 additions and 549 deletions

View File

@ -1,8 +1,9 @@
name: "CodeQL"
on:
workflow_dispatch:
push:
branches: ["master"]
branches: ["develop", "preview", "master"]
pull_request:
branches: ["develop", "preview", "master"]
schedule:

View File

@ -1,32 +1,33 @@
from lxml import html
from django.core.exceptions import ValidationError
from django.core.validators import URLValidator
# Django imports
from django.utils import timezone
from django.core.validators import URLValidator
from django.core.exceptions import ValidationError
from lxml import html
# Third party imports
from rest_framework import serializers
# Module imports
from plane.db.models import (
User,
Issue,
State,
IssueActivity,
IssueAssignee,
Label,
IssueAttachment,
IssueComment,
IssueLabel,
IssueLink,
IssueComment,
IssueAttachment,
IssueActivity,
Label,
ProjectMember,
State,
User,
)
from .base import BaseSerializer
from .cycle import CycleSerializer, CycleLiteSerializer
from .module import ModuleSerializer, ModuleLiteSerializer
from .user import UserLiteSerializer
from .cycle import CycleLiteSerializer, CycleSerializer
from .module import ModuleLiteSerializer, ModuleSerializer
from .state import StateLiteSerializer
from .user import UserLiteSerializer
class IssueSerializer(BaseSerializer):
@ -79,7 +80,7 @@ class IssueSerializer(BaseSerializer):
data["description_html"] = parsed_str
except Exception as e:
raise serializers.ValidationError(f"Invalid HTML: {str(e)}")
raise serializers.ValidationError("Invalid HTML passed")
# Validate assignees are from project
if data.get("assignees", []):
@ -294,7 +295,7 @@ class IssueLinkSerializer(BaseSerializer):
raise serializers.ValidationError("Invalid URL format.")
# Check URL scheme
if not value.startswith(('http://', 'https://')):
if not value.startswith(("http://", "https://")):
raise serializers.ValidationError("Invalid URL scheme.")
return value
@ -366,7 +367,7 @@ class IssueCommentSerializer(BaseSerializer):
data["comment_html"] = parsed_str
except Exception as e:
raise serializers.ValidationError(f"Invalid HTML: {str(e)}")
raise serializers.ValidationError("Invalid HTML passed")
return data

View File

@ -103,7 +103,8 @@ class CycleViewSet(WebhookMixin, BaseViewSet):
.annotate(is_favorite=Exists(favorite_subquery))
.annotate(
total_issues=Count(
"issue_cycle",
"issue_cycle__issue__id",
distinct=True,
filter=Q(
issue_cycle__issue__archived_at__isnull=True,
issue_cycle__issue__is_draft=False,
@ -112,7 +113,8 @@ class CycleViewSet(WebhookMixin, BaseViewSet):
)
.annotate(
completed_issues=Count(
"issue_cycle__issue__state__group",
"issue_cycle__issue__id",
distinct=True,
filter=Q(
issue_cycle__issue__state__group="completed",
issue_cycle__issue__archived_at__isnull=True,
@ -122,7 +124,8 @@ class CycleViewSet(WebhookMixin, BaseViewSet):
)
.annotate(
cancelled_issues=Count(
"issue_cycle__issue__state__group",
"issue_cycle__issue__id",
distinct=True,
filter=Q(
issue_cycle__issue__state__group="cancelled",
issue_cycle__issue__archived_at__isnull=True,
@ -132,7 +135,8 @@ class CycleViewSet(WebhookMixin, BaseViewSet):
)
.annotate(
started_issues=Count(
"issue_cycle__issue__state__group",
"issue_cycle__issue__id",
distinct=True,
filter=Q(
issue_cycle__issue__state__group="started",
issue_cycle__issue__archived_at__isnull=True,
@ -142,7 +146,8 @@ class CycleViewSet(WebhookMixin, BaseViewSet):
)
.annotate(
unstarted_issues=Count(
"issue_cycle__issue__state__group",
"issue_cycle__issue__id",
distinct=True,
filter=Q(
issue_cycle__issue__state__group="unstarted",
issue_cycle__issue__archived_at__isnull=True,
@ -152,7 +157,8 @@ class CycleViewSet(WebhookMixin, BaseViewSet):
)
.annotate(
backlog_issues=Count(
"issue_cycle__issue__state__group",
"issue_cycle__issue__id",
distinct=True,
filter=Q(
issue_cycle__issue__state__group="backlog",
issue_cycle__issue__archived_at__isnull=True,

View File

@ -1,54 +1,57 @@
# Python imports
import json
# Django Imports
from django.utils import timezone
from django.db.models import (
Prefetch,
F,
OuterRef,
Exists,
Count,
Q,
Func,
Subquery,
IntegerField,
)
from django.contrib.postgres.aggregates import ArrayAgg
from django.contrib.postgres.fields import ArrayField
from django.db.models import Value, UUIDField
from django.db.models import (
Count,
Exists,
F,
Func,
IntegerField,
OuterRef,
Prefetch,
Q,
Subquery,
UUIDField,
Value,
)
from django.db.models.functions import Coalesce
# Django Imports
from django.utils import timezone
from rest_framework import status
# Third party imports
from rest_framework.response import Response
from rest_framework import status
# Module imports
from .. import BaseViewSet, BaseAPIView, WebhookMixin
from plane.app.serializers import (
ModuleWriteSerializer,
ModuleSerializer,
ModuleLinkSerializer,
ModuleFavoriteSerializer,
ModuleUserPropertiesSerializer,
ModuleDetailSerializer,
)
from plane.app.permissions import (
ProjectEntityPermission,
ProjectLitePermission,
)
from plane.db.models import (
Module,
ModuleIssue,
Project,
Issue,
ModuleLink,
ModuleFavorite,
ModuleUserProperties,
from plane.app.serializers import (
ModuleDetailSerializer,
ModuleFavoriteSerializer,
ModuleLinkSerializer,
ModuleSerializer,
ModuleUserPropertiesSerializer,
ModuleWriteSerializer,
)
from plane.bgtasks.issue_activites_task import issue_activity
from plane.db.models import (
Issue,
Module,
ModuleFavorite,
ModuleIssue,
ModuleLink,
ModuleUserProperties,
Project,
)
from plane.utils.analytics_plot import burndown_plot
# Module imports
from .. import BaseAPIView, BaseViewSet, WebhookMixin
class ModuleViewSet(WebhookMixin, BaseViewSet):
model = Module
@ -392,9 +395,11 @@ class ModuleViewSet(WebhookMixin, BaseViewSet):
"completion_chart": {},
}
if queryset.first().start_date and queryset.first().target_date:
# Fetch the modules
modules = queryset.first()
if modules and modules.start_date and modules.target_date:
data["distribution"]["completion_chart"] = burndown_plot(
queryset=queryset.first(),
queryset=modules,
slug=slug,
project_id=project_id,
module_id=pk,

View File

@ -3,15 +3,10 @@ from rest_framework import status
from rest_framework.response import Response
# Module imports
from plane.app.permissions import WorkspaceEntityPermission
from plane.app.serializers import WorkspaceEstimateSerializer
from plane.app.views.base import BaseAPIView
from plane.db.models import Project, Estimate
from plane.app.permissions import WorkspaceEntityPermission
# Django imports
from django.db.models import (
Prefetch,
)
from plane.db.models import Estimate, Project
from plane.utils.cache import cache_response
@ -25,15 +20,11 @@ class WorkspaceEstimatesEndpoint(BaseAPIView):
estimate_ids = Project.objects.filter(
workspace__slug=slug, estimate__isnull=False
).values_list("estimate_id", flat=True)
estimates = Estimate.objects.filter(
pk__in=estimate_ids
).prefetch_related(
Prefetch(
"points",
queryset=Project.objects.select_related(
"estimate", "workspace"
),
)
estimates = (
Estimate.objects.filter(pk__in=estimate_ids, workspace__slug=slug)
.prefetch_related("points")
.select_related("workspace", "project")
)
serializer = WorkspaceEstimateSerializer(estimates, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)

File diff suppressed because it is too large Load Diff

View File

@ -4,18 +4,15 @@ import { Node } from "@tiptap/pm/model";
import { findListItemPos } from "src/ui/extensions/custom-list-keymap/list-helpers/find-list-item-pos";
import { hasListBefore } from "src/ui/extensions/custom-list-keymap/list-helpers/has-list-before";
import { hasListItemBefore } from "src/ui/extensions/custom-list-keymap/list-helpers/has-list-item-before";
import { listItemHasSubList } from "src/ui/extensions/custom-list-keymap/list-helpers/list-item-has-sub-list";
export const handleBackspace = (editor: Editor, name: string, parentListTypes: string[]) => {
// this is required to still handle the undo handling
if (editor.commands.undoInputRule()) {
return true;
}
// if the cursor is not at the start of a node
// do nothing and proceed
if (!isAtStartOfNode(editor.state)) {
return false;
}
// if the current item is NOT inside a list item &
// the previous item is a list (orderedList or bulletList)
// move the cursor into the list and delete the current item
@ -53,14 +50,31 @@ export const handleBackspace = (editor: Editor, name: string, parentListTypes: s
return false;
}
// if the cursor is not at the start of a node
// do nothing and proceed
if (!isAtStartOfNode(editor.state)) {
return false;
}
const listItemPos = findListItemPos(name, editor.state);
if (!listItemPos) {
return false;
}
// if current node is a list item and cursor it at start of a list node,
// simply lift the list item i.e. remove it as a list item (task/bullet/ordered)
// irrespective of above node being a list or not
const $prev = editor.state.doc.resolve(listItemPos.$pos.pos - 2);
const prevNode = $prev.node(listItemPos.depth);
const previousListItemHasSubList = listItemHasSubList(name, editor.state, prevNode);
// if the previous item is a list item and doesn't have a sublist, join the list items
if (hasListItemBefore(name, editor.state) && previousListItemHasSubList) {
return editor.chain().liftListItem(name).run();
// return editor.commands.joinItemBackward();
}
// otherwise in the end, a backspace should
// always just lift the list item if
// joining / merging is not possible
return editor.chain().liftListItem(name).run();
};

View File

@ -0,0 +1,21 @@
import { getNodeType } from "@tiptap/core";
import { Node } from "@tiptap/pm/model";
import { EditorState } from "@tiptap/pm/state";
export const listItemHasSubList = (typeOrName: string, state: EditorState, node?: Node) => {
if (!node) {
return false;
}
const nodeType = getNodeType(typeOrName, state.schema);
let hasSubList = false;
node.descendants((child) => {
if (child.type === nodeType) {
hasSubList = true;
}
});
return hasSubList;
};

View File

@ -41,12 +41,12 @@ export const CoreEditorExtensions = (
StarterKit.configure({
bulletList: {
HTMLAttributes: {
class: "list-disc list-outside leading-3 -mt-2",
class: "list-disc list-outside leading-3",
},
},
orderedList: {
HTMLAttributes: {
class: "list-decimal list-outside leading-3 -mt-2",
class: "list-decimal list-outside leading-3 -mt-2 -mb-2",
},
},
listItem: {
@ -98,7 +98,7 @@ export const CoreEditorExtensions = (
}),
TaskItem.configure({
HTMLAttributes: {
class: "flex items-start my-4",
class: "flex items-start mt-4",
},
nested: true,
}),

View File

@ -1,4 +1,7 @@
import { Extension } from "@tiptap/core";
import { Plugin, PluginKey, Transaction } from "@tiptap/pm/state";
import { canJoin } from "@tiptap/pm/transform";
import { NodeType } from "@tiptap/pm/model";
declare module "@tiptap/core" {
// eslint-disable-next-line no-unused-vars
@ -12,6 +15,51 @@ declare module "@tiptap/core" {
}
}
function autoJoin(tr: Transaction, newTr: Transaction, nodeType: NodeType) {
if (!tr.isGeneric) return false;
// Find all ranges where we might want to join.
const ranges: Array<number> = [];
for (let i = 0; i < tr.mapping.maps.length; i++) {
const map = tr.mapping.maps[i];
for (let j = 0; j < ranges.length; j++) ranges[j] = map.map(ranges[j]);
map.forEach((_s, _e, from, to) => ranges.push(from, to));
}
// Figure out which joinable points exist inside those ranges,
// by checking all node boundaries in their parent nodes.
const joinable = [];
for (let i = 0; i < ranges.length; i += 2) {
const from = ranges[i],
to = ranges[i + 1];
const $from = tr.doc.resolve(from),
depth = $from.sharedDepth(to),
parent = $from.node(depth);
for (let index = $from.indexAfter(depth), pos = $from.after(depth + 1); pos <= to; ++index) {
const after = parent.maybeChild(index);
if (!after) break;
if (index && joinable.indexOf(pos) == -1) {
const before = parent.child(index - 1);
if (before.type == after.type && before.type === nodeType) joinable.push(pos);
}
pos += after.nodeSize;
}
}
let joined = false;
// Join the joinable points
joinable.sort((a, b) => a - b);
for (let i = joinable.length - 1; i >= 0; i--) {
if (canJoin(tr.doc, joinable[i])) {
newTr.join(joinable[i]);
joined = true;
}
}
return joined;
}
export const CustomKeymap = Extension.create({
name: "CustomKeymap",
@ -32,6 +80,42 @@ export const CustomKeymap = Extension.create({
};
},
addProseMirrorPlugins() {
return [
new Plugin({
key: new PluginKey("ordered-list-merging"),
appendTransaction(transactions, oldState, newState) {
// Create a new transaction.
const newTr = newState.tr;
let joined = false;
for (const transaction of transactions) {
const anotherJoin = autoJoin(transaction, newTr, newState.schema.nodes["orderedList"]);
joined = anotherJoin || joined;
}
if (joined) {
return newTr;
}
},
}),
new Plugin({
key: new PluginKey("unordered-list-merging"),
appendTransaction(transactions, oldState, newState) {
// Create a new transaction.
const newTr = newState.tr;
let joined = false;
for (const transaction of transactions) {
const anotherJoin = autoJoin(transaction, newTr, newState.schema.nodes["bulletList"]);
joined = anotherJoin || joined;
}
if (joined) {
return newTr;
}
},
}),
];
},
addKeyboardShortcuts() {
return {
"Mod-a": ({ editor }) => {

View File

@ -28,12 +28,12 @@ export const CoreReadOnlyEditorExtensions = (mentionConfig: {
StarterKit.configure({
bulletList: {
HTMLAttributes: {
class: "list-disc list-outside leading-3 -mt-2",
class: "list-disc list-outside leading-3",
},
},
orderedList: {
HTMLAttributes: {
class: "list-decimal list-outside leading-3 -mt-2",
class: "list-decimal list-outside leading-3 -mt-2 -mb-2",
},
},
listItem: {
@ -81,7 +81,7 @@ export const CoreReadOnlyEditorExtensions = (mentionConfig: {
}),
TaskItem.configure({
HTMLAttributes: {
class: "flex items-start my-4",
class: "flex items-start mt-4",
},
nested: true,
}),

View File

@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-var-requires */
/** @type {import('next').NextConfig} */
require("dotenv").config({ path: ".env" });
const { withSentryConfig } = require("@sentry/nextjs");
@ -26,8 +27,11 @@ const nextConfig = {
output: "standalone",
};
if (parseInt(process.env.NEXT_PUBLIC_ENABLE_SENTRY || "0")) {
module.exports = withSentryConfig(nextConfig, { silent: true }, { hideSourceMaps: true });
if (parseInt(process.env.NEXT_PUBLIC_ENABLE_SENTRY || "0"), 10) {
module.exports = withSentryConfig(nextConfig,
{ silent: true, authToken: process.env.SENTRY_AUTH_TOKEN },
{ hideSourceMaps: true }
);
} else {
module.exports = nextConfig;
}

View File

@ -22,7 +22,7 @@
"@plane/rich-text-editor": "*",
"@plane/types": "*",
"@plane/ui": "*",
"@sentry/nextjs": "^7.85.0",
"@sentry/nextjs": "^7.108.0",
"axios": "^1.3.4",
"clsx": "^2.0.0",
"dotenv": "^16.3.1",

View File

@ -17,37 +17,25 @@
"NEXT_PUBLIC_POSTHOG_KEY",
"NEXT_PUBLIC_POSTHOG_HOST",
"NEXT_PUBLIC_POSTHOG_DEBUG",
"JITSU_TRACKER_ACCESS_KEY",
"JITSU_TRACKER_HOST"
"SENTRY_AUTH_TOKEN"
],
"pipeline": {
"build": {
"dependsOn": [
"^build"
],
"outputs": [
".next/**",
"dist/**"
]
"dependsOn": ["^build"],
"outputs": [".next/**", "dist/**"]
},
"develop": {
"cache": false,
"persistent": true,
"dependsOn": [
"^build"
]
"dependsOn": ["^build"]
},
"dev": {
"cache": false,
"persistent": true,
"dependsOn": [
"^build"
]
"dependsOn": ["^build"]
},
"test": {
"dependsOn": [
"^build"
],
"dependsOn": ["^build"],
"outputs": []
},
"lint": {

View File

@ -144,7 +144,7 @@ export const ImagePickerPopover: React.FC<Props> = observer((props) => {
useEffect(() => {
if (!unsplashImages || value !== null) return;
onChange(unsplashImages[0].urls.regular);
onChange(unsplashImages[0]?.urls.regular);
}, [value, onChange, unsplashImages]);
const handleClose = () => {

View File

@ -201,7 +201,7 @@ export const ActiveCycleStats: FC<ActiveCycleStatsProps> = observer((props) => {
as="div"
className="flex h-52 w-full flex-col gap-1 overflow-y-auto text-custom-text-200 vertical-scrollbar scrollbar-sm"
>
{cycleIssues.length > 0 ? (
{cycle?.distribution?.assignees && cycle.distribution.assignees.length > 0 ? (
cycle.distribution?.assignees?.map((assignee, index) => {
if (assignee.assignee_id)
return (
@ -246,8 +246,8 @@ export const ActiveCycleStats: FC<ActiveCycleStatsProps> = observer((props) => {
as="div"
className="flex h-52 w-full flex-col gap-1 overflow-y-auto text-custom-text-200 vertical-scrollbar scrollbar-sm"
>
{cycleIssues.length > 0 ? (
cycle.distribution?.labels?.map((label, index) => (
{cycle?.distribution?.labels && cycle.distribution.labels.length > 0 ? (
cycle.distribution.labels?.map((label, index) => (
<SingleProgressStats
key={label.label_id ?? `no-label-${index}`}
title={

View File

@ -1,4 +1,5 @@
import React from "react";
import { observer } from "mobx-react";
import { RefreshCw } from "lucide-react";
import { TIssue } from "@plane/types";
// types
@ -9,7 +10,7 @@ type Props = {
issueDetail?: TIssue;
};
export const IssueUpdateStatus: React.FC<Props> = (props) => {
export const IssueUpdateStatus: React.FC<Props> = observer((props) => {
const { isSubmitting, issueDetail } = props;
// hooks
const { getProjectById } = useProject();
@ -33,4 +34,4 @@ export const IssueUpdateStatus: React.FC<Props> = (props) => {
</div>
</>
);
};
});

View File

@ -1,4 +1,5 @@
import React from "react";
import { observer } from "mobx-react";
import Link from "next/link";
import { useRouter } from "next/router";
// hooks
@ -6,7 +7,7 @@ import { EUserWorkspaceRoles, WORKSPACE_SETTINGS_LINKS } from "@/constants/works
import { useUser } from "@/hooks/store";
// constants
export const WorkspaceSettingsSidebar = () => {
export const WorkspaceSettingsSidebar = observer(() => {
// router
const router = useRouter();
const { workspaceSlug } = router.query;
@ -44,4 +45,4 @@ export const WorkspaceSettingsSidebar = () => {
</div>
</div>
);
};
});

View File

@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-var-requires */
require("dotenv").config({ path: ".env" });
const { withSentryConfig } = require("@sentry/nextjs");
@ -24,8 +25,11 @@ const nextConfig = {
output: "standalone",
};
if (parseInt(process.env.NEXT_PUBLIC_ENABLE_SENTRY || "0")) {
module.exports = withSentryConfig(nextConfig, { silent: true }, { hideSourceMaps: true });
if (parseInt(process.env.NEXT_PUBLIC_ENABLE_SENTRY || "0"), 10) {
module.exports = withSentryConfig(nextConfig,
{ silent: true, authToken: process.env.SENTRY_AUTH_TOKEN },
{ hideSourceMaps: true }
);
} else {
module.exports = nextConfig;
}

View File

@ -28,7 +28,7 @@
"@plane/types": "*",
"@plane/ui": "*",
"@popperjs/core": "^2.11.8",
"@sentry/nextjs": "^7.85.0",
"@sentry/nextjs": "^7.108.0",
"axios": "^1.1.3",
"clsx": "^2.0.0",
"cmdk": "^0.2.0",

189
yarn.lock
View File

@ -2149,35 +2149,46 @@
dependencies:
"@daybrush/utils" "^1.4.0"
"@sentry-internal/feedback@7.91.0":
version "7.91.0"
resolved "https://registry.yarnpkg.com/@sentry-internal/feedback/-/feedback-7.91.0.tgz#be09e5aec2959fcf503e2cf78496d5e2d263bc5a"
integrity sha512-SJKTSaz68F5YIwF79EttBm915M2LnacgZMYRnRumyTmMKnebGhYQLwWbZdpaDvOa1U18dgRajDX8Qed/8A3tXw==
"@sentry-internal/feedback@7.108.0":
version "7.108.0"
resolved "https://registry.yarnpkg.com/@sentry-internal/feedback/-/feedback-7.108.0.tgz#7033352abd304f1383ec47640e056a0dfd5132b7"
integrity sha512-8JcgZEnk1uWrXJhsd3iRvFtEiVeaWOEhN0NZwhwQXHfvODqep6JtrkY1yCIyxbpA37aZmrPc2JhyotRERGfUjg==
dependencies:
"@sentry/core" "7.91.0"
"@sentry/types" "7.91.0"
"@sentry/utils" "7.91.0"
"@sentry/core" "7.108.0"
"@sentry/types" "7.108.0"
"@sentry/utils" "7.108.0"
"@sentry-internal/tracing@7.91.0":
version "7.91.0"
resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.91.0.tgz#fbb6e1e3383e1eeee08633384e004da73ac1c37d"
integrity sha512-JH5y6gs6BS0its7WF2DhySu7nkhPDfZcdpAXldxzIlJpqFkuwQKLU5nkYJpiIyZz1NHYYtW5aum2bV2oCOdDRA==
"@sentry-internal/replay-canvas@7.108.0":
version "7.108.0"
resolved "https://registry.yarnpkg.com/@sentry-internal/replay-canvas/-/replay-canvas-7.108.0.tgz#641133c19c0e1c423617b8d791f53d6cd0b0a862"
integrity sha512-R5tvjGqWUV5vSk0N1eBgVW7wIADinrkfDEBZ9FyKP2mXHBobsyNGt30heJDEqYmVqluRqjU2NuIRapsnnrpGnA==
dependencies:
"@sentry/core" "7.91.0"
"@sentry/types" "7.91.0"
"@sentry/utils" "7.91.0"
"@sentry/core" "7.108.0"
"@sentry/replay" "7.108.0"
"@sentry/types" "7.108.0"
"@sentry/utils" "7.108.0"
"@sentry/browser@7.91.0":
version "7.91.0"
resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.91.0.tgz#de3b9ae3ca7716a35cfabc97ac376944a67e6e34"
integrity sha512-lJv3x/xekzC/biiyAsVCioq2XnKNOZhI6jY3ZzLJZClYV8eKRi7D3KCsHRvMiCdGak1d/6sVp8F4NYY+YiWy1Q==
"@sentry-internal/tracing@7.108.0":
version "7.108.0"
resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.108.0.tgz#d1e660701fb860cfae72b6ebfa8fb267533421fa"
integrity sha512-zuK5XsTsb+U+hgn3SPetYDAogrXsM16U/LLoMW7+TlC6UjlHGYQvmX3o+M2vntejoU1QZS8m1bCAZSMWEypAEw==
dependencies:
"@sentry-internal/feedback" "7.91.0"
"@sentry-internal/tracing" "7.91.0"
"@sentry/core" "7.91.0"
"@sentry/replay" "7.91.0"
"@sentry/types" "7.91.0"
"@sentry/utils" "7.91.0"
"@sentry/core" "7.108.0"
"@sentry/types" "7.108.0"
"@sentry/utils" "7.108.0"
"@sentry/browser@7.108.0":
version "7.108.0"
resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.108.0.tgz#b95810bb6572b63781f253615896f5afb1a3a5c0"
integrity sha512-FNpzsdTvGvdHJMUelqEouUXMZU7jC+dpN7CdT6IoHVVFEkoAgrjMVUhXZoQ/dmCkdKWHmFSQhJ8Fm6V+e9Aq0A==
dependencies:
"@sentry-internal/feedback" "7.108.0"
"@sentry-internal/replay-canvas" "7.108.0"
"@sentry-internal/tracing" "7.108.0"
"@sentry/core" "7.108.0"
"@sentry/replay" "7.108.0"
"@sentry/types" "7.108.0"
"@sentry/utils" "7.108.0"
"@sentry/cli@^1.77.1":
version "1.77.1"
@ -2191,95 +2202,95 @@
proxy-from-env "^1.1.0"
which "^2.0.2"
"@sentry/core@7.91.0":
version "7.91.0"
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.91.0.tgz#229334d7f03dd5d90a17495e61ce4215ab730b2a"
integrity sha512-tu+gYq4JrTdrR+YSh5IVHF0fJi/Pi9y0HZ5H9HnYy+UMcXIotxf6hIEaC6ZKGeLWkGXffz2gKpQLe/g6vy/lPA==
"@sentry/core@7.108.0":
version "7.108.0"
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.108.0.tgz#a27e8d6f85f59c5730ce86071474f15ac899fde0"
integrity sha512-I/VNZCFgLASxHZaD0EtxZRM34WG9w2gozqgrKGNMzAymwmQ3K9g/1qmBy4e6iS3YRptb7J5UhQkZQHrcwBbjWQ==
dependencies:
"@sentry/types" "7.91.0"
"@sentry/utils" "7.91.0"
"@sentry/types" "7.108.0"
"@sentry/utils" "7.108.0"
"@sentry/integrations@7.91.0":
version "7.91.0"
resolved "https://registry.yarnpkg.com/@sentry/integrations/-/integrations-7.91.0.tgz#b0496c9e404783bc433b1d2464d8f9aa180ebc8e"
integrity sha512-LGRfb+WfG3FaWHtDnJIhtupweat0imCQr2z/5SSbQKzqxHhtlaEU+9IExBmBdzq90n4lRBaVQHA3zGuU02uOhg==
"@sentry/integrations@7.108.0":
version "7.108.0"
resolved "https://registry.yarnpkg.com/@sentry/integrations/-/integrations-7.108.0.tgz#307c61966208f2a126c1a93e712277c8f86a3d3c"
integrity sha512-b/WbK1f3x2rQ4aJJSA4VSwpBXrXFm1Nzrca3Y9qW0MI1wjZEYsDDrh9m6ulLdVBl4YDc2VqYp1COwU/NjuHlog==
dependencies:
"@sentry/core" "7.91.0"
"@sentry/types" "7.91.0"
"@sentry/utils" "7.91.0"
"@sentry/core" "7.108.0"
"@sentry/types" "7.108.0"
"@sentry/utils" "7.108.0"
localforage "^1.8.1"
"@sentry/nextjs@^7.85.0":
version "7.91.0"
resolved "https://registry.yarnpkg.com/@sentry/nextjs/-/nextjs-7.91.0.tgz#42eb3af10ff230e8a3fe9f0e50cdbac94b7d290e"
integrity sha512-wE83+OTEH4yYnDrhMw9eVEARSfZc6xY5qJb9xyYm5rW3+gVjNQZQaUY+wkM61Xdo0T35BN+7U4T88HbwzGeMqA==
"@sentry/nextjs@^7.108.0":
version "7.108.0"
resolved "https://registry.yarnpkg.com/@sentry/nextjs/-/nextjs-7.108.0.tgz#31d903d75bbf4b4530046360daff4d51dcf62f53"
integrity sha512-etBrMSLRbNAzozetBeL6D+lR9lRAyHmV7NUBGCX9lQvgmcdxkQa15EX8pIKjsMejZ8xAZNsqYVIByIs67A77rg==
dependencies:
"@rollup/plugin-commonjs" "24.0.0"
"@sentry/core" "7.91.0"
"@sentry/integrations" "7.91.0"
"@sentry/node" "7.91.0"
"@sentry/react" "7.91.0"
"@sentry/types" "7.91.0"
"@sentry/utils" "7.91.0"
"@sentry/vercel-edge" "7.91.0"
"@sentry/core" "7.108.0"
"@sentry/integrations" "7.108.0"
"@sentry/node" "7.108.0"
"@sentry/react" "7.108.0"
"@sentry/types" "7.108.0"
"@sentry/utils" "7.108.0"
"@sentry/vercel-edge" "7.108.0"
"@sentry/webpack-plugin" "1.21.0"
chalk "3.0.0"
resolve "1.22.8"
rollup "2.78.0"
stacktrace-parser "^0.1.10"
"@sentry/node@7.91.0":
version "7.91.0"
resolved "https://registry.yarnpkg.com/@sentry/node/-/node-7.91.0.tgz#26bf13c3daf988f9725afd1a3cc38ba2ff90d62a"
integrity sha512-hTIfSQxD7L+AKIqyjoq8CWBRkEQrrMZmA3GSZgPI5JFWBHgO0HBo5TH/8TU81oEJh6kqqHAl2ObMhmcnaFqlzg==
"@sentry/node@7.108.0":
version "7.108.0"
resolved "https://registry.yarnpkg.com/@sentry/node/-/node-7.108.0.tgz#ed113dc1d39aaae32f7e9f681dcea41cf28eb5f1"
integrity sha512-pMxc9txnDDkU4Z8k2Uw/DPSLPehNtWV3mjJ3+my0AMORGYrXLkJI93tddlE5z/7k+GEJdj1HsOLgxUN0OU+HGA==
dependencies:
"@sentry-internal/tracing" "7.91.0"
"@sentry/core" "7.91.0"
"@sentry/types" "7.91.0"
"@sentry/utils" "7.91.0"
https-proxy-agent "^5.0.0"
"@sentry-internal/tracing" "7.108.0"
"@sentry/core" "7.108.0"
"@sentry/types" "7.108.0"
"@sentry/utils" "7.108.0"
"@sentry/react@7.91.0":
version "7.91.0"
resolved "https://registry.yarnpkg.com/@sentry/react/-/react-7.91.0.tgz#620e6ce9452af025d2cc1b2eca3dd1dd730dc439"
integrity sha512-7JH2rWaX3WKHHvBcZQ4f/KnkYIXTf7hMojRFncUwPocdtDlhJw/JUvjAYNpEysixXIgsMes3B32lmtZjGjRhwQ==
"@sentry/react@7.108.0":
version "7.108.0"
resolved "https://registry.yarnpkg.com/@sentry/react/-/react-7.108.0.tgz#26a50324f6d7a9576f3753c099e7bcd8def94f3c"
integrity sha512-C60arh5/gtO42eMU9l34aWlKDLZUO+1j1goaEf/XRSwUcyJS9tbJrs+mT4nbKxUsEG714It2gRbfSEvh1eXmCg==
dependencies:
"@sentry/browser" "7.91.0"
"@sentry/types" "7.91.0"
"@sentry/utils" "7.91.0"
"@sentry/browser" "7.108.0"
"@sentry/core" "7.108.0"
"@sentry/types" "7.108.0"
"@sentry/utils" "7.108.0"
hoist-non-react-statics "^3.3.2"
"@sentry/replay@7.91.0":
version "7.91.0"
resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.91.0.tgz#95077868aee3c3cc670affe13156434f858e1755"
integrity sha512-XwbesnLLNtaVXKtDoyBB96GxJuhGi9zy3a662Ba/McmumCnkXrMQYpQPh08U7MgkTyDRgjDwm7PXDhiKpcb03g==
"@sentry/replay@7.108.0":
version "7.108.0"
resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.108.0.tgz#baa679bd19b4e3729e607d3f84cff5048aeb3415"
integrity sha512-jo8fDOzcZJclP1+4n9jUtVxTlBFT9hXwxhAMrhrt70FV/nfmCtYQMD3bzIj79nwbhUtFP6pN39JH1o7Xqt1hxQ==
dependencies:
"@sentry-internal/tracing" "7.91.0"
"@sentry/core" "7.91.0"
"@sentry/types" "7.91.0"
"@sentry/utils" "7.91.0"
"@sentry-internal/tracing" "7.108.0"
"@sentry/core" "7.108.0"
"@sentry/types" "7.108.0"
"@sentry/utils" "7.108.0"
"@sentry/types@7.91.0":
version "7.91.0"
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.91.0.tgz#5b68954e08986fecb0d4bef168df58eef62c32c7"
integrity sha512-bcQnb7J3P3equbCUc+sPuHog2Y47yGD2sCkzmnZBjvBT0Z1B4f36fI/5WjyZhTjLSiOdg3F2otwvikbMjmBDew==
"@sentry/types@7.108.0":
version "7.108.0"
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.108.0.tgz#5ceb959c4dabe511fc441fec8c2465f2d624900f"
integrity sha512-bKtHITmBN3kqtqE5eVvL8mY8znM05vEodENwRpcm6TSrrBjC2RnwNWVwGstYDdHpNfFuKwC8mLY9bgMJcENo8g==
"@sentry/utils@7.91.0":
version "7.91.0"
resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.91.0.tgz#3b1a94c053c885877908cd3e1365e3d23e21a73f"
integrity sha512-fvxjrEbk6T6Otu++Ax9ntlQ0sGRiwSC179w68aC3u26Wr30FAIRKqHTCCdc2jyWk7Gd9uWRT/cq+g8NG/8BfSg==
"@sentry/utils@7.108.0":
version "7.108.0"
resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.108.0.tgz#0231042956aed2ef35809891592238530349dfd9"
integrity sha512-a45yEFD5qtgZaIFRAcFkG8C8lnDzn6t4LfLXuV4OafGAy/3ZAN3XN8wDnrruHkiUezSSANGsLg3bXaLW/JLvJw==
dependencies:
"@sentry/types" "7.91.0"
"@sentry/types" "7.108.0"
"@sentry/vercel-edge@7.91.0":
version "7.91.0"
resolved "https://registry.yarnpkg.com/@sentry/vercel-edge/-/vercel-edge-7.91.0.tgz#df67ee39d10570b71eccf831a181c064974d62b1"
integrity sha512-CounqhXPwFh67zf6L/q4ACBHHqknT6YY9LdgIAnUd0GGgHzrJPyKcthvh8Je4lNdpo5LFg2gnR+6g6JS8DDYDQ==
"@sentry/vercel-edge@7.108.0":
version "7.108.0"
resolved "https://registry.yarnpkg.com/@sentry/vercel-edge/-/vercel-edge-7.108.0.tgz#c5ca35094bc46029ec5a72f7ee09fd3705582baa"
integrity sha512-dUuUEswaVIzsJnzTfaJxrvkfOowrlJxxHo2AybPDym2rob7CdaLdDJIYJa83X7QeAKMkTgLny/gYSQYC0E4UyA==
dependencies:
"@sentry-internal/tracing" "7.91.0"
"@sentry/core" "7.91.0"
"@sentry/types" "7.91.0"
"@sentry/utils" "7.91.0"
"@sentry-internal/tracing" "7.108.0"
"@sentry/core" "7.108.0"
"@sentry/types" "7.108.0"
"@sentry/utils" "7.108.0"
"@sentry/webpack-plugin@1.21.0":
version "1.21.0"