mirror of
https://github.com/umami-software/umami.git
synced 2025-12-06 01:18:00 +01:00
Updated prisma.
This commit is contained in:
parent
b45971da33
commit
b9d52af215
13 changed files with 493 additions and 167 deletions
|
|
@ -66,13 +66,13 @@
|
||||||
"@dicebear/core": "^9.2.3",
|
"@dicebear/core": "^9.2.3",
|
||||||
"@fontsource/inter": "^5.2.8",
|
"@fontsource/inter": "^5.2.8",
|
||||||
"@hello-pangea/dnd": "^17.0.0",
|
"@hello-pangea/dnd": "^17.0.0",
|
||||||
"@prisma/adapter-pg": "^6.18.0",
|
"@prisma/adapter-pg": "^7.0.0",
|
||||||
"@prisma/client": "^6.18.0",
|
"@prisma/client": "^7.0.0",
|
||||||
"@prisma/extension-read-replicas": "^0.4.1",
|
"@prisma/extension-read-replicas": "^0.4.1",
|
||||||
"@react-spring/web": "^10.0.3",
|
"@react-spring/web": "^10.0.3",
|
||||||
"@svgr/cli": "^8.1.0",
|
"@svgr/cli": "^8.1.0",
|
||||||
"@tanstack/react-query": "^5.90.5",
|
"@tanstack/react-query": "^5.90.5",
|
||||||
"@umami/react-zen": "^0.208.0",
|
"@umami/react-zen": "^0.210.0",
|
||||||
"@umami/redis-client": "^0.29.0",
|
"@umami/redis-client": "^0.29.0",
|
||||||
"bcryptjs": "^3.0.2",
|
"bcryptjs": "^3.0.2",
|
||||||
"chalk": "^5.6.2",
|
"chalk": "^5.6.2",
|
||||||
|
|
@ -107,7 +107,7 @@
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"papaparse": "^5.5.3",
|
"papaparse": "^5.5.3",
|
||||||
"pg": "^8.16.3",
|
"pg": "^8.16.3",
|
||||||
"prisma": "^6.18.0",
|
"prisma": "^7.0.0",
|
||||||
"pure-rand": "^7.0.1",
|
"pure-rand": "^7.0.1",
|
||||||
"react": "^19.2.0",
|
"react": "^19.2.0",
|
||||||
"react-dom": "^19.2.0",
|
"react-dom": "^19.2.0",
|
||||||
|
|
|
||||||
494
pnpm-lock.yaml
generated
494
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
8
prisma.config.ts
Normal file
8
prisma.config.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
import 'dotenv/config';
|
||||||
|
import { defineConfig, env } from 'prisma/config';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
datasource: {
|
||||||
|
url: env('DATABASE_URL'),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
@ -6,7 +6,6 @@ generator client {
|
||||||
|
|
||||||
datasource db {
|
datasource db {
|
||||||
provider = "postgresql"
|
provider = "postgresql"
|
||||||
url = env("DATABASE_URL")
|
|
||||||
relationMode = "prisma"
|
relationMode = "prisma"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,19 @@
|
||||||
{
|
{
|
||||||
"name": "",
|
"name": "",
|
||||||
"short_name": "",
|
"short_name": "",
|
||||||
"icons": [
|
"icons": [
|
||||||
{
|
{
|
||||||
"src": "/android-chrome-192x192.png",
|
"src": "/android-chrome-192x192.png",
|
||||||
"sizes": "192x192",
|
"sizes": "192x192",
|
||||||
"type": "image/png"
|
"type": "image/png"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src": "/android-chrome-512x512.png",
|
"src": "/android-chrome-512x512.png",
|
||||||
"sizes": "512x512",
|
"sizes": "512x512",
|
||||||
"type": "image/png"
|
"type": "image/png"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"theme_color": "#ffffff",
|
"theme_color": "#ffffff",
|
||||||
"background_color": "#ffffff",
|
"background_color": "#ffffff",
|
||||||
"display": "standalone"
|
"display": "standalone"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,21 +50,23 @@ const downloadDirect = (url, originalUrl) =>
|
||||||
https.get(url, res => {
|
https.get(url, res => {
|
||||||
// Follow redirects
|
// Follow redirects
|
||||||
if (res.statusCode === 301 || res.statusCode === 302) {
|
if (res.statusCode === 301 || res.statusCode === 302) {
|
||||||
downloadDirect(res.headers.location, originalUrl || url).then(resolve).catch(reject);
|
downloadDirect(res.headers.location, originalUrl || url)
|
||||||
|
.then(resolve)
|
||||||
|
.catch(reject);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const filename = path.join(dest, path.basename(originalUrl || url));
|
const filename = path.join(dest, path.basename(originalUrl || url));
|
||||||
const fileStream = fs.createWriteStream(filename);
|
const fileStream = fs.createWriteStream(filename);
|
||||||
|
|
||||||
res.pipe(fileStream);
|
res.pipe(fileStream);
|
||||||
|
|
||||||
fileStream.on('finish', () => {
|
fileStream.on('finish', () => {
|
||||||
fileStream.close();
|
fileStream.close();
|
||||||
console.log('Saved geo database:', filename);
|
console.log('Saved geo database:', filename);
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
|
|
||||||
fileStream.on('error', e => {
|
fileStream.on('error', e => {
|
||||||
reject(e);
|
reject(e);
|
||||||
});
|
});
|
||||||
|
|
@ -78,27 +80,29 @@ if (isDirectMmdb) {
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
downloadCompressed(url).then(
|
downloadCompressed(url)
|
||||||
res =>
|
.then(
|
||||||
new Promise((resolve, reject) => {
|
res =>
|
||||||
res.on('entry', entry => {
|
new Promise((resolve, reject) => {
|
||||||
if (entry.path.endsWith('.mmdb')) {
|
res.on('entry', entry => {
|
||||||
const filename = path.join(dest, path.basename(entry.path));
|
if (entry.path.endsWith('.mmdb')) {
|
||||||
entry.pipe(fs.createWriteStream(filename));
|
const filename = path.join(dest, path.basename(entry.path));
|
||||||
|
entry.pipe(fs.createWriteStream(filename));
|
||||||
|
|
||||||
console.log('Saved geo database:', filename);
|
console.log('Saved geo database:', filename);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
res.on('error', e => {
|
res.on('error', e => {
|
||||||
reject(e);
|
reject(e);
|
||||||
});
|
});
|
||||||
res.on('finish', () => {
|
res.on('finish', () => {
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
).catch(e => {
|
)
|
||||||
console.error('Failed to download geo database:', e);
|
.catch(e => {
|
||||||
process.exit(1);
|
console.error('Failed to download geo database:', e);
|
||||||
});
|
process.exit(1);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
'use client';
|
'use client';
|
||||||
import { Grid, Loading, Column, Row } from '@umami/react-zen';
|
import { Column, Grid, Loading, Row } from '@umami/react-zen';
|
||||||
import Script from 'next/script';
|
import Script from 'next/script';
|
||||||
import { UpdateNotice } from './UpdateNotice';
|
|
||||||
import { SideNav } from '@/app/(main)/SideNav';
|
|
||||||
import { useLoginQuery, useConfig, useNavigation } from '@/components/hooks';
|
|
||||||
import { MobileNav } from '@/app/(main)/MobileNav';
|
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { removeItem, setItem } from '@/lib/storage';
|
import { MobileNav } from '@/app/(main)/MobileNav';
|
||||||
|
import { SideNav } from '@/app/(main)/SideNav';
|
||||||
|
import { useConfig, useLoginQuery, useNavigation } from '@/components/hooks';
|
||||||
import { LAST_TEAM_CONFIG } from '@/lib/constants';
|
import { LAST_TEAM_CONFIG } from '@/lib/constants';
|
||||||
|
import { removeItem, setItem } from '@/lib/storage';
|
||||||
|
import { UpdateNotice } from './UpdateNotice';
|
||||||
|
|
||||||
export function App({ children }) {
|
export function App({ children }) {
|
||||||
const { user, isLoading, error } = useLoginQuery();
|
const { user, isLoading, error } = useLoginQuery();
|
||||||
|
|
@ -27,7 +27,9 @@ export function App({ children }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
window.location.href = `${process.env.basePath || ''}/login`;
|
window.location.href = config.cloudMode
|
||||||
|
? `${process.env.cloudUrl}/login`
|
||||||
|
: `${process.env.basePath || ''}/login`;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -208,7 +208,7 @@
|
||||||
|
|
||||||
.start:before,
|
.start:before,
|
||||||
.end:before {
|
.end:before {
|
||||||
content: '';
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
border: 3px solid var(--journey-line-color);
|
border: 3px solid var(--journey-line-color);
|
||||||
|
|
|
||||||
|
|
@ -137,11 +137,6 @@ export function MetricLabel({ type, data }: MetricLabelProps) {
|
||||||
return formatValue(label, 'language');
|
return formatValue(label, 'language');
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return (
|
return <FilterLink type={type} value={label} />;
|
||||||
<FilterLink
|
|
||||||
type={type}
|
|
||||||
value={label}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,23 +14,21 @@ describe('renderNumberLabels', () => {
|
||||||
expect(renderNumberLabels(input)).toBe(expected);
|
expect(renderNumberLabels(input)).toBe(expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
test.each([['12500', '12.5k']])(
|
test.each([
|
||||||
"formats numbers ≥ 10K as 'X.Xk' (%s → %s)",
|
['12500', '12.5k'],
|
||||||
(input, expected) => {
|
])("formats numbers ≥ 10K as 'X.Xk' (%s → %s)", (input, expected) => {
|
||||||
expect(renderNumberLabels(input)).toBe(expected);
|
expect(renderNumberLabels(input)).toBe(expected);
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
||||||
test.each([['1500', '1.50k']])("formats numbers ≥ 1K as 'X.XXk' (%s → %s)", (input, expected) => {
|
test.each([['1500', '1.50k']])("formats numbers ≥ 1K as 'X.XXk' (%s → %s)", (input, expected) => {
|
||||||
expect(renderNumberLabels(input)).toBe(expected);
|
expect(renderNumberLabels(input)).toBe(expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
test.each([['999', '999']])(
|
test.each([
|
||||||
'calls formatNumber for values < 1000 (%s → %s)',
|
['999', '999'],
|
||||||
(input, expected) => {
|
])('calls formatNumber for values < 1000 (%s → %s)', (input, expected) => {
|
||||||
expect(renderNumberLabels(input)).toBe(expected);
|
expect(renderNumberLabels(input)).toBe(expected);
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
||||||
test.each([
|
test.each([
|
||||||
['0', '0'],
|
['0', '0'],
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import debug from 'debug';
|
|
||||||
import { PrismaPg } from '@prisma/adapter-pg';
|
import { PrismaPg } from '@prisma/adapter-pg';
|
||||||
import { readReplicas } from '@prisma/extension-read-replicas';
|
import { readReplicas } from '@prisma/extension-read-replicas';
|
||||||
|
import debug from 'debug';
|
||||||
import { PrismaClient } from '@/generated/prisma/client';
|
import { PrismaClient } from '@/generated/prisma/client';
|
||||||
import { SESSION_COLUMNS, OPERATORS, DEFAULT_PAGE_SIZE, FILTER_COLUMNS } from './constants';
|
import { DEFAULT_PAGE_SIZE, FILTER_COLUMNS, OPERATORS, SESSION_COLUMNS } from './constants';
|
||||||
import { QueryOptions, QueryFilters, Operator } from './types';
|
|
||||||
import { filtersObjectToArray } from './params';
|
import { filtersObjectToArray } from './params';
|
||||||
|
import type { Operator, QueryFilters, QueryOptions } from './types';
|
||||||
|
|
||||||
const log = debug('umami:prisma');
|
const log = debug('umami:prisma');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { Prisma } from '@/generated/prisma/client';
|
import type { Prisma } from '@/generated/prisma/client';
|
||||||
import prisma from '@/lib/prisma';
|
import prisma from '@/lib/prisma';
|
||||||
import { QueryFilters } from '@/lib/types';
|
import type { QueryFilters } from '@/lib/types';
|
||||||
|
|
||||||
export async function findPixel(criteria: Prisma.PixelFindUniqueArgs) {
|
export async function findPixel(criteria: Prisma.PixelFindUniqueArgs) {
|
||||||
return prisma.client.pixel.findUnique(criteria);
|
return prisma.client.pixel.findUnique(criteria);
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ body {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
html[style*='padding-right'] {
|
html[style*="padding-right"] {
|
||||||
padding-right: 0 !important;
|
padding-right: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue