mirror of
https://github.com/kremalicious/umami.git
synced 2025-02-01 12:29:35 +01:00
Added comparison tables.
This commit is contained in:
parent
626fe14fc2
commit
b7a7d4de4d
24
README.md
24
README.md
@ -1,27 +1,25 @@
|
||||
<p align="center">
|
||||
<img src="https://github.com/shubhusion/umami/blob/master/src/assets/logo-white.svg" alt="Umami Logo" width="100">
|
||||
<img src="https://umami.is/images/umami-logo.png" alt="Umami Logo" width="100">
|
||||
</p>
|
||||
|
||||
<h1 align="center">Umami</h1>
|
||||
|
||||
<p align="center"><b>Empowering insights. Preserving privacy.</b></p>
|
||||
|
||||
<p align="center">
|
||||
<i>Umami is a simple, fast, privacy-focused alternative to Google Analytics.</i>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/umami-software/umami/releases">
|
||||
<img src="https://img.shields.io/github/release/umami-software/umami.svg" alt="GitHub Release">
|
||||
<img src="https://img.shields.io/github/release/umami-software/umami.svg" alt="GitHub Release" />
|
||||
</a>
|
||||
<a href="https://github.com/umami-software/umami/blob/master/LICENSE">
|
||||
<img src="https://img.shields.io/github/license/umami-software/umami.svg" alt="MIT License">
|
||||
<img src="https://img.shields.io/github/license/umami-software/umami.svg" alt="MIT License" />
|
||||
</a>
|
||||
<a href="https://github.com/umami-software/umami/actions">
|
||||
<img src="https://img.shields.io/github/actions/workflow/status/umami-software/umami/ci.yml" alt="Build Status">
|
||||
<img src="https://img.shields.io/github/actions/workflow/status/umami-software/umami/ci.yml" alt="Build Status" />
|
||||
</a>
|
||||
<a href="https://analytics.umami.is/share/LGazGOecbDtaIwDr/umami.is" style="text-decoration: none;">
|
||||
<img src="https://img.shields.io/badge/Try%20Demo%20Now-Click%20Here-brightgreen" alt="Umami Demo">
|
||||
<img src="https://img.shields.io/badge/Try%20Demo%20Now-Click%20Here-brightgreen" alt="Umami Demo" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
@ -128,20 +126,20 @@ docker compose up --force-recreate
|
||||
|
||||
---
|
||||
|
||||
## 📞 Contact
|
||||
## 🛟 Support
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/umami-software/umami">
|
||||
<img src="https://img.shields.io/badge/GitHub--blue?style=social&logo=github" alt="GitHub">
|
||||
<img src="https://img.shields.io/badge/GitHub--blue?style=social&logo=github" alt="GitHub" />
|
||||
</a>
|
||||
<a href="https://twitter.com/umami_software">
|
||||
<img src="https://img.shields.io/badge/Twitter--blue?style=social&logo=twitter" alt="Twitter">
|
||||
<img src="https://img.shields.io/badge/Twitter--blue?style=social&logo=twitter" alt="Twitter" />
|
||||
</a>
|
||||
<a href="https://linkedin.com/company/umami-software">
|
||||
<img src="https://img.shields.io/badge/LinkedIn--blue?style=social&logo=linkedin" alt="LinkedIn">
|
||||
<img src="https://img.shields.io/badge/LinkedIn--blue?style=social&logo=linkedin" alt="LinkedIn" />
|
||||
</a>
|
||||
<a href="https://discord.com/invite/4dz4zcXYrQ">
|
||||
<img src="https://img.shields.io/badge/Discord--blue?style=social&logo=discord" alt="Discord">
|
||||
<a href="https://umami.is/discord">
|
||||
<img src="https://img.shields.io/badge/Discord--blue?style=social&logo=discord" alt="Discord" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
|
@ -64,9 +64,9 @@
|
||||
".next/cache"
|
||||
],
|
||||
"dependencies": {
|
||||
"@clickhouse/client": "^1.0.1",
|
||||
"@clickhouse/client": "^1.0.2",
|
||||
"@fontsource/inter": "^4.5.15",
|
||||
"@prisma/client": "5.13.0",
|
||||
"@prisma/client": "5.14.0",
|
||||
"@prisma/extension-read-replicas": "^0.3.0",
|
||||
"@react-spring/web": "^9.7.3",
|
||||
"@tanstack/react-query": "^5.28.6",
|
||||
@ -102,7 +102,7 @@
|
||||
"next-basics": "^0.39.0",
|
||||
"node-fetch": "^3.2.8",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prisma": "5.13.0",
|
||||
"prisma": "5.14.0",
|
||||
"react": "^18.2.0",
|
||||
"react-basics": "^0.123.0",
|
||||
"react-beautiful-dnd": "^13.1.0",
|
||||
|
@ -70,7 +70,7 @@ export function WebsiteMetricsBar({
|
||||
|
||||
const items = [
|
||||
{ label: formatMessage(labels.previousPeriod), value: 'prev' },
|
||||
{ label: formatMessage(labels.yearOverYear), value: 'yoy' },
|
||||
{ label: formatMessage(labels.previousYear), value: 'yoy' },
|
||||
];
|
||||
|
||||
return (
|
||||
|
@ -4,4 +4,11 @@
|
||||
|
||||
.nav {
|
||||
width: 200px;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: var(--base800);
|
||||
text-align: center;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { useState } from 'react';
|
||||
import SideNav from 'components/layout/SideNav';
|
||||
import { useMessages, useNavigation } from 'components/hooks';
|
||||
import { useDateRange, useMessages, useNavigation } from 'components/hooks';
|
||||
import PagesTable from 'components/metrics/PagesTable';
|
||||
import ReferrersTable from 'components/metrics/ReferrersTable';
|
||||
import BrowsersTable from 'components/metrics/BrowsersTable';
|
||||
@ -13,11 +14,12 @@ import LanguagesTable from 'components/metrics/LanguagesTable';
|
||||
import EventsTable from 'components/metrics/EventsTable';
|
||||
import QueryParametersTable from 'components/metrics/QueryParametersTable';
|
||||
import { Grid, GridRow } from 'components/layout/Grid';
|
||||
import styles from './WebsiteCompareTables.module.css';
|
||||
import { useContext, useState } from 'react';
|
||||
import MetricsTable from 'components/metrics/MetricsTable';
|
||||
import FilterLink from 'components/common/FilterLink';
|
||||
import { WebsiteContext } from '../WebsiteProvider';
|
||||
import useStore from 'store/websites';
|
||||
import { getCompareDate } from 'lib/date';
|
||||
import { formatNumber } from 'lib/format';
|
||||
import ChangeLabel from 'components/metrics/ChangeLabel';
|
||||
import styles from './WebsiteCompareTables.module.css';
|
||||
|
||||
const views = {
|
||||
url: PagesTable,
|
||||
@ -36,14 +38,15 @@ const views = {
|
||||
};
|
||||
|
||||
export function WebsiteCompareTables({ websiteId }: { websiteId: string }) {
|
||||
const { domain } = useContext(WebsiteContext);
|
||||
const [data, setData] = useState([]);
|
||||
const { dateRange } = useDateRange(websiteId);
|
||||
const dateCompare = useStore(state => state[websiteId]?.dateCompare);
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const {
|
||||
renderUrl,
|
||||
query: { view },
|
||||
} = useNavigation();
|
||||
const Component: typeof MetricsTable = views[view] || (() => null);
|
||||
const Component: typeof MetricsTable = views[view || 'url'] || (() => null);
|
||||
|
||||
const items = [
|
||||
{
|
||||
@ -108,27 +111,48 @@ export function WebsiteCompareTables({ websiteId }: { websiteId: string }) {
|
||||
},
|
||||
];
|
||||
|
||||
const renderLabel = ({ x, y }, index) => {
|
||||
return (
|
||||
<FilterLink
|
||||
id={view}
|
||||
value={x}
|
||||
label={!x && formatMessage(labels.none)}
|
||||
externalUrl={
|
||||
view === 'url' ? `${domain.startsWith('http') ? domain : `https://${domain}`}${x}` : null
|
||||
}
|
||||
>
|
||||
{y} : {data[index]?.y} !
|
||||
</FilterLink>
|
||||
);
|
||||
const renderChange = ({ x, y }) => {
|
||||
const prev = data.find(d => d.x === x)?.y;
|
||||
const value = y - prev;
|
||||
const change = Math.abs(((y - prev) / prev) * 100);
|
||||
|
||||
return !isNaN(change) && <ChangeLabel value={value}>{formatNumber(change)}%</ChangeLabel>;
|
||||
};
|
||||
|
||||
const { startDate, endDate } = getCompareDate(
|
||||
dateCompare,
|
||||
dateRange.startDate,
|
||||
dateRange.endDate,
|
||||
);
|
||||
|
||||
const params = {
|
||||
startAt: startDate.getTime(),
|
||||
endAt: endDate.getTime(),
|
||||
};
|
||||
|
||||
return (
|
||||
<Grid className={styles.container}>
|
||||
<GridRow columns="compare">
|
||||
<SideNav className={styles.nav} items={items} selectedKey={view} shallow={true} />
|
||||
<Component websiteId={websiteId} limit={20} showMore={false} onDataLoad={setData} />
|
||||
<Component websiteId={websiteId} limit={20} showMore={false} renderLabel={renderLabel} />
|
||||
<div>
|
||||
<div className={styles.title}>{formatMessage(labels.previous)}</div>
|
||||
<Component
|
||||
websiteId={websiteId}
|
||||
limit={20}
|
||||
showMore={false}
|
||||
onDataLoad={setData}
|
||||
params={params}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div className={styles.title}> {formatMessage(labels.current)}</div>
|
||||
<Component
|
||||
websiteId={websiteId}
|
||||
limit={20}
|
||||
showMore={false}
|
||||
renderChange={renderChange}
|
||||
/>
|
||||
</div>
|
||||
</GridRow>
|
||||
</Grid>
|
||||
);
|
||||
|
@ -4,7 +4,7 @@ import { useFilterParams } from '../useFilterParams';
|
||||
|
||||
export function useWebsiteMetrics(
|
||||
websiteId: string,
|
||||
query: { type: string; limit: number; search: string },
|
||||
queryParams: { type: string; limit: number; search: string; startAt?: number; endAt?: number },
|
||||
options?: Omit<UseQueryOptions & { onDataLoad?: (data: any) => void }, 'queryKey' | 'queryFn'>,
|
||||
) {
|
||||
const { get, useQuery } = useApi();
|
||||
@ -16,17 +16,17 @@ export function useWebsiteMetrics(
|
||||
{
|
||||
websiteId,
|
||||
...params,
|
||||
...query,
|
||||
...queryParams,
|
||||
},
|
||||
],
|
||||
queryFn: async () => {
|
||||
const filters = { ...params };
|
||||
|
||||
filters[query.type] = undefined;
|
||||
filters[queryParams.type] = undefined;
|
||||
|
||||
const data = await get(`/websites/${websiteId}/metrics`, {
|
||||
...filters,
|
||||
...query,
|
||||
...queryParams,
|
||||
});
|
||||
|
||||
options?.onDataLoad?.(data);
|
||||
|
@ -253,8 +253,10 @@ export const labels = defineMessages({
|
||||
defaultMessage: 'Understand how users nagivate through your website.',
|
||||
},
|
||||
compare: { id: 'label.compare', defaultMessage: 'Compare' },
|
||||
current: { id: 'label.current', defaultMessage: 'Current' },
|
||||
previous: { id: 'label.previous', defaultMessage: 'Previous' },
|
||||
previousPeriod: { id: 'label.previous-period', defaultMessage: 'Previous period' },
|
||||
yearOverYear: { id: 'label.year-over-year', defaultMessage: 'Year over year' },
|
||||
previousYear: { id: 'label.previous-year', defaultMessage: 'Previous year' },
|
||||
});
|
||||
|
||||
export const messages = defineMessages({
|
||||
|
31
src/components/metrics/ChangeLabel.module.css
Normal file
31
src/components/metrics/ChangeLabel.module.css
Normal file
@ -0,0 +1,31 @@
|
||||
.label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
padding: 0.1em 0.5em;
|
||||
border-radius: 5px;
|
||||
color: var(--base500);
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
.positive {
|
||||
color: var(--green700);
|
||||
background: var(--green100);
|
||||
}
|
||||
|
||||
.negative {
|
||||
color: var(--red700);
|
||||
background: var(--red100);
|
||||
}
|
||||
|
||||
.neutral {
|
||||
color: var(--base700);
|
||||
background: var(--base100);
|
||||
}
|
||||
|
||||
.new {
|
||||
color: var(--blue900);
|
||||
background: var(--blue100);
|
||||
}
|
44
src/components/metrics/ChangeLabel.tsx
Normal file
44
src/components/metrics/ChangeLabel.tsx
Normal file
@ -0,0 +1,44 @@
|
||||
import classNames from 'classnames';
|
||||
import { Icon, Icons } from 'react-basics';
|
||||
import { ReactNode } from 'react';
|
||||
import styles from './ChangeLabel.module.css';
|
||||
|
||||
export function ChangeLabel({
|
||||
value,
|
||||
size,
|
||||
reverseColors,
|
||||
className,
|
||||
children,
|
||||
}: {
|
||||
value: number;
|
||||
size?: 'xs' | 'sm' | 'md' | 'lg';
|
||||
reverseColors?: boolean;
|
||||
showPercentage?: boolean;
|
||||
className?: string;
|
||||
children?: ReactNode;
|
||||
}) {
|
||||
const positive = value * (reverseColors ? -1 : 1) >= 0;
|
||||
const negative = value * (reverseColors ? -1 : 1) < 0;
|
||||
const isNew = isNaN(value);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames(styles.label, className, {
|
||||
[styles.positive]: positive,
|
||||
[styles.negative]: negative,
|
||||
[styles.neutral]: value === 0,
|
||||
[styles.new]: isNew,
|
||||
})}
|
||||
title={value.toString()}
|
||||
>
|
||||
{!isNew && (
|
||||
<Icon rotate={value === 0 ? 0 : positive || reverseColors ? -45 : 45} size={size}>
|
||||
<Icons.ArrowRight />
|
||||
</Icon>
|
||||
)}
|
||||
{children || value}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ChangeLabel;
|
@ -72,9 +72,11 @@
|
||||
}
|
||||
|
||||
.value {
|
||||
width: 50px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
text-align: end;
|
||||
margin-inline-end: 10px;
|
||||
margin-inline-end: 5px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@ export interface ListTableProps {
|
||||
metric?: string;
|
||||
className?: string;
|
||||
renderLabel?: (row: any, index: number) => ReactNode;
|
||||
renderChange?: (row: any, index: number) => ReactNode;
|
||||
animate?: boolean;
|
||||
virtualize?: boolean;
|
||||
showPercentage?: boolean;
|
||||
@ -27,6 +28,7 @@ export function ListTable({
|
||||
metric,
|
||||
className,
|
||||
renderLabel,
|
||||
renderChange,
|
||||
animate = true,
|
||||
virtualize = false,
|
||||
showPercentage = true,
|
||||
@ -45,6 +47,7 @@ export function ListTable({
|
||||
percent={percent}
|
||||
animate={animate && !virtualize}
|
||||
showPercentage={showPercentage}
|
||||
change={renderChange ? renderChange(row, index) : null}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@ -78,7 +81,7 @@ export function ListTable({
|
||||
);
|
||||
}
|
||||
|
||||
const AnimatedRow = ({ label, value = 0, percent, animate, showPercentage = true }) => {
|
||||
const AnimatedRow = ({ label, value = 0, percent, change, animate, showPercentage = true }) => {
|
||||
const props = useSpring({
|
||||
width: percent,
|
||||
y: value,
|
||||
@ -90,6 +93,7 @@ const AnimatedRow = ({ label, value = 0, percent, animate, showPercentage = true
|
||||
<div className={styles.row}>
|
||||
<div className={styles.label}>{label}</div>
|
||||
<div className={styles.value}>
|
||||
{change}
|
||||
<animated.div className={styles.value} title={props?.y as any}>
|
||||
{props.y?.to(formatLongNumber)}
|
||||
</animated.div>
|
||||
|
@ -35,29 +35,3 @@
|
||||
white-space: nowrap;
|
||||
color: var(--base800);
|
||||
}
|
||||
|
||||
.change {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
padding: 0.1em 0.5em;
|
||||
border-radius: 5px;
|
||||
color: var(--base500);
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
.change.positive {
|
||||
color: var(--green700);
|
||||
background: var(--green100);
|
||||
}
|
||||
|
||||
.change.negative {
|
||||
color: var(--red700);
|
||||
background: var(--red100);
|
||||
}
|
||||
|
||||
.hide {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import classNames from 'classnames';
|
||||
import { Icon, Icons } from 'react-basics';
|
||||
import { useSpring, animated } from '@react-spring/web';
|
||||
import { formatNumber } from 'lib/format';
|
||||
import ChangeLabel from 'components/metrics/ChangeLabel';
|
||||
import styles from './MetricCard.module.css';
|
||||
|
||||
export interface MetricCardProps {
|
||||
@ -31,30 +31,19 @@ export const MetricCard = ({
|
||||
const props = useSpring({ x: Number(value) || 0, from: { x: 0 } });
|
||||
const changeProps = useSpring({ x: Number(change) || 0, from: { x: 0 } });
|
||||
const prevProps = useSpring({ x: Number(value - change) || 0, from: { x: 0 } });
|
||||
const positive = change * (reverseColors ? -1 : 1) >= 0;
|
||||
const negative = change * (reverseColors ? -1 : 1) < 0;
|
||||
|
||||
return (
|
||||
<div className={classNames(styles.card, className, showPrevious && styles.compare)}>
|
||||
{showLabel && <div className={styles.label}>{label}</div>}
|
||||
<animated.div className={styles.value} title={props?.x as any}>
|
||||
<animated.div className={styles.value} title={value.toString()}>
|
||||
{props?.x?.to(x => format(x))}
|
||||
</animated.div>
|
||||
{showChange && (
|
||||
<div
|
||||
className={classNames(styles.change, {
|
||||
[styles.positive]: positive,
|
||||
[styles.negative]: negative,
|
||||
[styles.hide]: ~~change === 0,
|
||||
})}
|
||||
>
|
||||
<Icon rotate={positive || reverseColors ? -45 : 45} size={showPrevious ? 'md' : 'xs'}>
|
||||
<Icons.ArrowRight />
|
||||
</Icon>
|
||||
<animated.span title={changeProps?.x as any}>
|
||||
<ChangeLabel className={styles.change} value={change} reverseColors={reverseColors}>
|
||||
<animated.span title={change.toString()}>
|
||||
{changeProps?.x?.to(x => format(Math.abs(x)))}
|
||||
</animated.span>
|
||||
</div>
|
||||
</ChangeLabel>
|
||||
)}
|
||||
{showPrevious && (
|
||||
<animated.div className={classNames(styles.value, styles.prev)} title={prevProps?.x as any}>
|
||||
|
@ -27,6 +27,7 @@ export interface MetricsTableProps extends ListTableProps {
|
||||
onSearch?: (search: string) => void;
|
||||
allowSearch?: boolean;
|
||||
showMore?: boolean;
|
||||
params?: { [key: string]: any };
|
||||
children?: ReactNode;
|
||||
}
|
||||
|
||||
@ -40,6 +41,7 @@ export function MetricsTable({
|
||||
delay = null,
|
||||
allowSearch = false,
|
||||
showMore = true,
|
||||
params,
|
||||
children,
|
||||
...props
|
||||
}: MetricsTableProps) {
|
||||
@ -51,7 +53,7 @@ export function MetricsTable({
|
||||
|
||||
const { data, isLoading, isFetched, error } = useWebsiteMetrics(
|
||||
websiteId,
|
||||
{ type, limit, search },
|
||||
{ type, limit, search, ...params },
|
||||
{
|
||||
retryDelay: delay || DEFAULT_ANIMATION_DURATION,
|
||||
onDataLoad,
|
||||
|
@ -55,7 +55,7 @@ export function PagesTable({ allowFilter, ...props }: PagesTableProps) {
|
||||
type={view}
|
||||
metric={formatMessage(labels.views)}
|
||||
dataFilter={emptyFilter}
|
||||
renderLabel={props.renderLabel || renderLink}
|
||||
renderLabel={renderLink}
|
||||
>
|
||||
{allowFilter && <FilterButtons items={buttons} selectedKey={view} onSelect={handleSelect} />}
|
||||
</MetricsTable>
|
||||
|
@ -46,7 +46,7 @@ export function PageviewsChart({ data, unit, isLoading, ...props }: PageviewsCha
|
||||
? [
|
||||
{
|
||||
type: 'line',
|
||||
label: `${formatMessage(labels.visits)} (VS)`,
|
||||
label: `${formatMessage(labels.visits)} (${formatMessage(labels.previous)})`,
|
||||
data: data.compare.pageviews,
|
||||
borderWidth: 2,
|
||||
backgroundColor: '#8601B0',
|
||||
@ -55,7 +55,7 @@ export function PageviewsChart({ data, unit, isLoading, ...props }: PageviewsCha
|
||||
},
|
||||
{
|
||||
type: 'line',
|
||||
label: `${formatMessage(labels.visitors)} (VS)`,
|
||||
label: `${formatMessage(labels.visitors)} (${formatMessage(labels.previous)})`,
|
||||
data: data.compare.sessions,
|
||||
borderWidth: 2,
|
||||
backgroundColor: '#f15bb5',
|
||||
|
@ -87,7 +87,7 @@ export default async (req: NextApiRequestCollect, res: NextApiResponse) => {
|
||||
|
||||
if (req.method === 'POST') {
|
||||
if (!process.env.DISABLE_BOT_CHECK && isbot(req.headers['user-agent'])) {
|
||||
return ok(res);
|
||||
return ok(res, { beep: 'boop' });
|
||||
}
|
||||
|
||||
await useValidate(schema, req, res);
|
||||
|
123
yarn.lock
123
yarn.lock
@ -1206,17 +1206,17 @@
|
||||
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
|
||||
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
|
||||
|
||||
"@clickhouse/client-common@1.0.1":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@clickhouse/client-common/-/client-common-1.0.1.tgz#c7dde5eafaad8189649373ecc23354c7a32847b3"
|
||||
integrity sha512-3L6e0foP6VOktScoi6XWMjJyOpKCWgLUYgPVxP2c7gm6Kotq+iRmmmXtXTSg7B7uozcLZycTtPfIw2d80SYsYw==
|
||||
"@clickhouse/client-common@1.0.2":
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@clickhouse/client-common/-/client-common-1.0.2.tgz#0fe0a4b33101c08d85c1279e4d74b2a92d42d996"
|
||||
integrity sha512-5oI2URFsXlzoysv5lAxoTUAnAHjXnaJ+1Jz3HUARR06Hkbr1sN0pGxfGwgjEd8E/lI4+UNdNEZicG2rlFnWSaA==
|
||||
|
||||
"@clickhouse/client@^1.0.1":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@clickhouse/client/-/client-1.0.1.tgz#364db28d9ef9beaf19104f962c2b06090cb10468"
|
||||
integrity sha512-fluUNnE2R7COJ6rn6DorYfi4D+AQn3t2qeBtEq37bQV3pD4EbKrBfKAwJ13e1lmMWdQ2B9bJUTMqGsRIDdWhJw==
|
||||
"@clickhouse/client@^1.0.2":
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@clickhouse/client/-/client-1.0.2.tgz#7d9675e697ce697f1e6777f4c66ca6d3384e7325"
|
||||
integrity sha512-PaK0GLjIrlCpXevrp9gliOrurna6MjMMFBgZhDh6Zup8IuJCjQru4LkNsWUl3hJ2nua6+Ygag14iB8ILbeaIjg==
|
||||
dependencies:
|
||||
"@clickhouse/client-common" "1.0.1"
|
||||
"@clickhouse/client-common" "1.0.2"
|
||||
|
||||
"@colors/colors@1.5.0":
|
||||
version "1.5.0"
|
||||
@ -2089,51 +2089,51 @@
|
||||
resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33"
|
||||
integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==
|
||||
|
||||
"@prisma/client@5.13.0":
|
||||
version "5.13.0"
|
||||
resolved "https://registry.yarnpkg.com/@prisma/client/-/client-5.13.0.tgz#b9f1d0983d714e982675201d8222a9ecb4bdad4a"
|
||||
integrity sha512-uYdfpPncbZ/syJyiYBwGZS8Gt1PTNoErNYMuqHDa2r30rNSFtgTA/LXsSk55R7pdRTMi5pHkeP9B14K6nHmwkg==
|
||||
"@prisma/client@5.14.0":
|
||||
version "5.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@prisma/client/-/client-5.14.0.tgz#dadca5bb1137ddcebb454bbdaf89423823d3363f"
|
||||
integrity sha512-akMSuyvLKeoU4LeyBAUdThP/uhVP3GuLygFE3MlYzaCb3/J8SfsYBE5PkaFuLuVpLyA6sFoW+16z/aPhNAESqg==
|
||||
|
||||
"@prisma/debug@5.13.0":
|
||||
version "5.13.0"
|
||||
resolved "https://registry.yarnpkg.com/@prisma/debug/-/debug-5.13.0.tgz#d88b0f6fafa0c216e20e284ed9fc30f1cbe45786"
|
||||
integrity sha512-699iqlEvzyCj9ETrXhs8o8wQc/eVW+FigSsHpiskSFydhjVuwTJEfj/nIYqTaWFYuxiWQRfm3r01meuW97SZaQ==
|
||||
"@prisma/debug@5.14.0":
|
||||
version "5.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@prisma/debug/-/debug-5.14.0.tgz#1227c705893c38284f7c63d72441480ebaa12605"
|
||||
integrity sha512-iq56qBZuFfX3fCxoxT8gBX33lQzomBU0qIUaEj1RebsKVz1ob/BVH1XSBwwwvRVtZEV1b7Fxx2eVu34Ge/mg3w==
|
||||
|
||||
"@prisma/engines-version@5.13.0-23.b9a39a7ee606c28e3455d0fd60e78c3ba82b1a2b":
|
||||
version "5.13.0-23.b9a39a7ee606c28e3455d0fd60e78c3ba82b1a2b"
|
||||
resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-5.13.0-23.b9a39a7ee606c28e3455d0fd60e78c3ba82b1a2b.tgz#a72a4fb83ba1fd01ad45f795aa55168f60d34723"
|
||||
integrity sha512-AyUuhahTINGn8auyqYdmxsN+qn0mw3eg+uhkp8zwknXYIqoT3bChG4RqNY/nfDkPvzWAPBa9mrDyBeOnWSgO6A==
|
||||
"@prisma/engines-version@5.14.0-25.e9771e62de70f79a5e1c604a2d7c8e2a0a874b48":
|
||||
version "5.14.0-25.e9771e62de70f79a5e1c604a2d7c8e2a0a874b48"
|
||||
resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-5.14.0-25.e9771e62de70f79a5e1c604a2d7c8e2a0a874b48.tgz#019c3c75a5c3276e580685fe48cdbfd181176858"
|
||||
integrity sha512-ip6pNkRo1UxWv+6toxNcYvItNYaqQjXdFNGJ+Nuk2eYtRoEdoF13wxo7/jsClJFFenMPVNVqXQDV0oveXnR1cA==
|
||||
|
||||
"@prisma/engines@5.13.0":
|
||||
version "5.13.0"
|
||||
resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-5.13.0.tgz#8994ebf7b4e35aee7746a8465ec22738379bcab6"
|
||||
integrity sha512-hIFLm4H1boj6CBZx55P4xKby9jgDTeDG0Jj3iXtwaaHmlD5JmiDkZhh8+DYWkTGchu+rRF36AVROLnk0oaqhHw==
|
||||
"@prisma/engines@5.14.0":
|
||||
version "5.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-5.14.0.tgz#2ee91dd2220a726c27c906fbea788bbb3efdac6e"
|
||||
integrity sha512-lgxkKZ6IEygVcw6IZZUlPIfLQ9hjSYAtHjZ5r64sCLDgVzsPFCi2XBBJgzPMkOQ5RHzUD4E/dVdpn9+ez8tk1A==
|
||||
dependencies:
|
||||
"@prisma/debug" "5.13.0"
|
||||
"@prisma/engines-version" "5.13.0-23.b9a39a7ee606c28e3455d0fd60e78c3ba82b1a2b"
|
||||
"@prisma/fetch-engine" "5.13.0"
|
||||
"@prisma/get-platform" "5.13.0"
|
||||
"@prisma/debug" "5.14.0"
|
||||
"@prisma/engines-version" "5.14.0-25.e9771e62de70f79a5e1c604a2d7c8e2a0a874b48"
|
||||
"@prisma/fetch-engine" "5.14.0"
|
||||
"@prisma/get-platform" "5.14.0"
|
||||
|
||||
"@prisma/extension-read-replicas@^0.3.0":
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@prisma/extension-read-replicas/-/extension-read-replicas-0.3.0.tgz#2842a7c928f957c1dd58a6256104797596d43426"
|
||||
integrity sha512-F9+rSmYday6GT2qjhJtkZcBOpLO5LtpvFcMGqrBDHf+78LEdSuxfFjOxYlNuqk4B+th62yxpbhfpmB9/Mca14Q==
|
||||
|
||||
"@prisma/fetch-engine@5.13.0":
|
||||
version "5.13.0"
|
||||
resolved "https://registry.yarnpkg.com/@prisma/fetch-engine/-/fetch-engine-5.13.0.tgz#9b6945c7b38bb59e840f8905b20ea7a3d059ca55"
|
||||
integrity sha512-Yh4W+t6YKyqgcSEB3odBXt7QyVSm0OQlBSldQF2SNXtmOgMX8D7PF/fvH6E6qBCpjB/yeJLy/FfwfFijoHI6sA==
|
||||
"@prisma/fetch-engine@5.14.0":
|
||||
version "5.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@prisma/fetch-engine/-/fetch-engine-5.14.0.tgz#45297c118d4ec3fea55129886edd5a429da1f6da"
|
||||
integrity sha512-VrheA9y9DMURK5vu8OJoOgQpxOhas3qF0IBHJ8G/0X44k82kc8E0w98HCn2nhnbOOMwbWsJWXfLC2/F8n5u0gQ==
|
||||
dependencies:
|
||||
"@prisma/debug" "5.13.0"
|
||||
"@prisma/engines-version" "5.13.0-23.b9a39a7ee606c28e3455d0fd60e78c3ba82b1a2b"
|
||||
"@prisma/get-platform" "5.13.0"
|
||||
"@prisma/debug" "5.14.0"
|
||||
"@prisma/engines-version" "5.14.0-25.e9771e62de70f79a5e1c604a2d7c8e2a0a874b48"
|
||||
"@prisma/get-platform" "5.14.0"
|
||||
|
||||
"@prisma/get-platform@5.13.0":
|
||||
version "5.13.0"
|
||||
resolved "https://registry.yarnpkg.com/@prisma/get-platform/-/get-platform-5.13.0.tgz#99ef909a52b9d79b64d72d2d3d8210c4892b6572"
|
||||
integrity sha512-B/WrQwYTzwr7qCLifQzYOmQhZcFmIFhR81xC45gweInSUn2hTEbfKUPd2keAog+y5WI5xLAFNJ3wkXplvSVkSw==
|
||||
"@prisma/get-platform@5.14.0":
|
||||
version "5.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@prisma/get-platform/-/get-platform-5.14.0.tgz#69112d3dde61905f59a65ed818f153e153ca40f0"
|
||||
integrity sha512-/yAyBvcEjRv41ynZrhdrPtHgk47xLRRq/o5eWGcUpBJ1YrUZTYB8EoPiopnP7iQrMATK8stXQdPOoVlrzuTQZw==
|
||||
dependencies:
|
||||
"@prisma/debug" "5.13.0"
|
||||
"@prisma/debug" "5.14.0"
|
||||
|
||||
"@react-spring/animated@~9.7.3":
|
||||
version "9.7.3"
|
||||
@ -8659,12 +8659,12 @@ pretty-format@^29.0.0, pretty-format@^29.7.0:
|
||||
ansi-styles "^5.0.0"
|
||||
react-is "^18.0.0"
|
||||
|
||||
prisma@5.13.0:
|
||||
version "5.13.0"
|
||||
resolved "https://registry.yarnpkg.com/prisma/-/prisma-5.13.0.tgz#1f06e20ccfb6038ad68869e6eacd3b346f9d0851"
|
||||
integrity sha512-kGtcJaElNRAdAGsCNykFSZ7dBKpL14Cbs+VaQ8cECxQlRPDjBlMHNFYeYt0SKovAVy2Y65JXQwB3A5+zIQwnTg==
|
||||
prisma@5.14.0:
|
||||
version "5.14.0"
|
||||
resolved "https://registry.yarnpkg.com/prisma/-/prisma-5.14.0.tgz#ffc4696a43b044b636c3303b7aa98c13c2ade4dd"
|
||||
integrity sha512-gCNZco7y5XtjrnQYeDJTiVZmT/ncqCr5RY1/Cf8X2wgLRmyh9ayPAGBNziI4qEE4S6SxCH5omQLVo9lmURaJ/Q==
|
||||
dependencies:
|
||||
"@prisma/engines" "5.13.0"
|
||||
"@prisma/engines" "5.14.0"
|
||||
|
||||
process@^0.11.10:
|
||||
version "0.11.10"
|
||||
@ -9590,16 +9590,7 @@ string-length@^4.0.1:
|
||||
char-regex "^1.0.2"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
"string-width-cjs@npm:string-width@^4.2.0":
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||
dependencies:
|
||||
emoji-regex "^8.0.0"
|
||||
is-fullwidth-code-point "^3.0.0"
|
||||
strip-ansi "^6.0.1"
|
||||
|
||||
string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
|
||||
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||
@ -9672,14 +9663,7 @@ string.prototype.trimstart@^1.0.8:
|
||||
define-properties "^1.2.1"
|
||||
es-object-atoms "^1.0.0"
|
||||
|
||||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||
dependencies:
|
||||
ansi-regex "^5.0.1"
|
||||
|
||||
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||
@ -10440,7 +10424,7 @@ which@^2.0.1:
|
||||
dependencies:
|
||||
isexe "^2.0.0"
|
||||
|
||||
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
|
||||
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
||||
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
||||
@ -10458,15 +10442,6 @@ wrap-ansi@^6.2.0:
|
||||
string-width "^4.1.0"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
wrap-ansi@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
||||
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
||||
dependencies:
|
||||
ansi-styles "^4.0.0"
|
||||
string-width "^4.1.0"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
wrap-ansi@^8.0.1, wrap-ansi@^8.1.0:
|
||||
version "8.1.0"
|
||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"
|
||||
|
Loading…
Reference in New Issue
Block a user