mirror of
https://github.com/diced/zipline.git
synced 2025-12-12 07:40:45 -08:00
feat: updates & bigint
This commit is contained in:
48
package.json
48
package.json
@@ -10,7 +10,9 @@
|
||||
"build:server": "tsup",
|
||||
"dev": "pnpm run build:server && pnpm run dev:server",
|
||||
"dev:server": "NODE_ENV=development DEBUG=zipline node --require dotenv/config --enable-source-maps ./build/server.js",
|
||||
"dev:inspector": "NODE_ENV=development DEBUG=zipline node --require dotenv/config --inspect=0.0.0.0:9229 --enable-source-maps ./build/server.js",
|
||||
"start": "NODE_ENV=production node --require dotenv/config --enable-source-maps ./build/server.js",
|
||||
"start:inspector": "NODE_ENV=production node --require dotenv/config --inspect=0.0.0.0:9229 --enable-source-maps ./build/server.js",
|
||||
"validate": "pnpm run \"/^validate:.*/\"",
|
||||
"validate:lint": "eslint --cache --ignore-path .gitignore --fix .",
|
||||
"validate:format": "prettier --write --ignore-path .gitignore .",
|
||||
@@ -21,45 +23,45 @@
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@emotion/server": "^11.11.0",
|
||||
"@github/webauthn-json": "^2.1.1",
|
||||
"@mantine/core": "^6.0.14",
|
||||
"@mantine/dates": "^6.0.19",
|
||||
"@mantine/dropzone": "^6.0.14",
|
||||
"@mantine/form": "^6.0.14",
|
||||
"@mantine/hooks": "^6.0.14",
|
||||
"@mantine/modals": "^6.0.14",
|
||||
"@mantine/next": "^6.0.14",
|
||||
"@mantine/notifications": "^6.0.14",
|
||||
"@mantine/nprogress": "^6.0.14",
|
||||
"@prisma/client": "^5.2.0",
|
||||
"@prisma/internals": "^5.2.0",
|
||||
"@prisma/migrate": "^5.2.0",
|
||||
"@tabler/icons-react": "^2.23.0",
|
||||
"@mantine/core": "^6.0.21",
|
||||
"@mantine/dates": "^6.0.21",
|
||||
"@mantine/dropzone": "^6.0.21",
|
||||
"@mantine/form": "^6.0.21",
|
||||
"@mantine/hooks": "^6.0.21",
|
||||
"@mantine/modals": "^6.0.21",
|
||||
"@mantine/next": "^6.0.21",
|
||||
"@mantine/notifications": "^6.0.21",
|
||||
"@mantine/nprogress": "^6.0.21",
|
||||
"@prisma/client": "^5.6.0",
|
||||
"@prisma/internals": "^5.6.0",
|
||||
"@prisma/migrate": "^5.6.0",
|
||||
"@tabler/icons-react": "^2.42.0",
|
||||
"@xoi/gps-metadata-remover": "^1.1.2",
|
||||
"argon2": "^0.30.3",
|
||||
"bytes": "^3.1.2",
|
||||
"colorette": "^2.0.20",
|
||||
"dayjs": "^1.11.8",
|
||||
"dayjs": "^1.11.10",
|
||||
"dotenv": "^16.3.1",
|
||||
"express": "^4.18.2",
|
||||
"ffmpeg-static": "^5.2.0",
|
||||
"highlight.js": "^11.8.0",
|
||||
"isomorphic-dompurify": "^1.8.0",
|
||||
"katex": "^0.16.8",
|
||||
"mantine-datatable": "^2.8.2",
|
||||
"highlight.js": "^11.9.0",
|
||||
"isomorphic-dompurify": "^1.9.0",
|
||||
"katex": "^0.16.9",
|
||||
"mantine-datatable": "^2.9.14",
|
||||
"ms": "^2.1.3",
|
||||
"multer": "^1.4.5-lts.1",
|
||||
"next": "^13.4.7",
|
||||
"next": "^14.0.3",
|
||||
"otplib": "^12.0.1",
|
||||
"qrcode": "^1.5.3",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-markdown": "^8.0.7",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"sharp": "^0.32.4",
|
||||
"sharp": "^0.32.6",
|
||||
"swr": "^2.2.0",
|
||||
"znv": "^0.3.2",
|
||||
"zod": "^3.21.4",
|
||||
"zustand": "^4.3.8"
|
||||
"zod": "^3.22.4",
|
||||
"zustand": "^4.4.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bytes": "^3.1.1",
|
||||
@@ -79,7 +81,7 @@
|
||||
"eslint-plugin-prettier": "^5.0.0",
|
||||
"eslint-plugin-unused-imports": "^3.0.0",
|
||||
"prettier": "^3.0.2",
|
||||
"prisma": "^5.2.0",
|
||||
"prisma": "^5.6.0",
|
||||
"tsup": "^7.0.0",
|
||||
"typescript": "^5.1.3"
|
||||
},
|
||||
|
||||
2510
pnpm-lock.yaml
generated
2510
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -121,7 +121,7 @@ model File {
|
||||
|
||||
name String // name & file saved on datasource
|
||||
originalName String? // original name of file when uploaded
|
||||
size Int
|
||||
size BigInt
|
||||
type String
|
||||
views Int @default(0)
|
||||
maxViews Int?
|
||||
|
||||
@@ -18,12 +18,13 @@ type ApiPaginationOptions = {
|
||||
};
|
||||
|
||||
const fetcher = async (
|
||||
{ options }: { options: ApiPaginationOptions } = {
|
||||
{ options }: { options: ApiPaginationOptions; key: string } = {
|
||||
options: {
|
||||
page: 1,
|
||||
},
|
||||
key: '/api/user/files',
|
||||
},
|
||||
) => {
|
||||
): Promise<Response['/api/user/files']> => {
|
||||
const searchParams = new URLSearchParams();
|
||||
if (options.page) searchParams.append('page', options.page.toString());
|
||||
if (options.filter) searchParams.append('filter', options.filter);
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
Collapse,
|
||||
Grid,
|
||||
Group,
|
||||
Paper,
|
||||
Progress,
|
||||
Text,
|
||||
Title,
|
||||
@@ -80,7 +81,12 @@ export default function UploadFile() {
|
||||
</Tooltip>
|
||||
</Group>
|
||||
|
||||
<Dropzone onDrop={(f) => setFiles([...f, ...files])} my='sm' loading={dropLoading}>
|
||||
<Dropzone
|
||||
onDrop={(f) => setFiles([...f, ...files])}
|
||||
my='sm'
|
||||
loading={dropLoading}
|
||||
disabled={dropLoading}
|
||||
>
|
||||
<Group position='center' spacing='xl' style={{ minHeight: rem(220), pointerEvents: 'none' }}>
|
||||
<Dropzone.Accept>
|
||||
<IconUpload
|
||||
@@ -114,8 +120,18 @@ export default function UploadFile() {
|
||||
</Group>
|
||||
</Dropzone>
|
||||
|
||||
<Collapse in={progress !== 0}>
|
||||
{progress !== 0 && <Progress my='sm' label={`${Math.floor(progress)}%`} value={progress} animate />}
|
||||
<Collapse in={progress > 0 && progress < 100}>
|
||||
{progress > 0 && progress < 100 && (
|
||||
<Progress my='sm' size='xl' label={`${Math.floor(progress)}%`} value={progress} animate />
|
||||
)}
|
||||
</Collapse>
|
||||
|
||||
<Collapse in={progress === 100}>
|
||||
<Paper withBorder p='xs' radius='sm'>
|
||||
<Text align='center' size='sm' color='yellow'>
|
||||
Finalizing upload(s)...
|
||||
</Text>
|
||||
</Paper>
|
||||
</Collapse>
|
||||
|
||||
<Grid grow my='sm'>
|
||||
|
||||
@@ -106,8 +106,9 @@ export function uploadFiles(
|
||||
|
||||
const req = new XMLHttpRequest();
|
||||
|
||||
req.addEventListener('progress', (e) => {
|
||||
req.upload.addEventListener('progress', (e) => {
|
||||
if (e.lengthComputable) {
|
||||
console.log(e.loaded, e.total);
|
||||
setProgress(Math.round((e.loaded / e.total) * 100));
|
||||
}
|
||||
});
|
||||
@@ -119,11 +120,11 @@ export function uploadFiles(
|
||||
setLoading(false);
|
||||
setProgress(0);
|
||||
|
||||
if ((res as ErrorBody).error) {
|
||||
if ((res as ErrorBody).code) {
|
||||
notifications.update({
|
||||
id: 'upload',
|
||||
title: 'Error uploading files',
|
||||
message: (res as ErrorBody).error,
|
||||
message: (res as ErrorBody).message,
|
||||
color: 'red',
|
||||
icon: <IconFileXFilled size='1rem' />,
|
||||
autoClose: true,
|
||||
|
||||
@@ -331,7 +331,7 @@ function parse(value: string, type: EnvType) {
|
||||
case 'boolean':
|
||||
return boolean(value);
|
||||
case 'byte':
|
||||
return bytes(Number(value));
|
||||
return bytes(value);
|
||||
case 'ms':
|
||||
return msFn(value);
|
||||
case 'json[]':
|
||||
|
||||
@@ -28,6 +28,14 @@ function getClient() {
|
||||
|
||||
const client = new PrismaClient().$extends({
|
||||
result: {
|
||||
file: {
|
||||
size: {
|
||||
needs: { size: true },
|
||||
compute({ size }: { size: bigint }) {
|
||||
return Number(size);
|
||||
},
|
||||
},
|
||||
},
|
||||
user: {
|
||||
view: {
|
||||
needs: { view: true },
|
||||
|
||||
@@ -4,6 +4,12 @@ import { Handler } from './combine';
|
||||
export function functions() {
|
||||
return (handler: Handler) => {
|
||||
return async (req: NextApiReq, res: NextApiRes) => {
|
||||
// res.json = (data?: any) => {
|
||||
// return res.send(
|
||||
// JSON.stringify(data, (key, value) => (typeof value === 'bigint' ? Number(value) : value)),
|
||||
// );
|
||||
// };
|
||||
|
||||
res.ok = (data?: any) => {
|
||||
return res.status(200).json(data);
|
||||
};
|
||||
|
||||
@@ -67,15 +67,15 @@ export async function queryStats(): Promise<MetricData> {
|
||||
files: file._count,
|
||||
urls: url._count,
|
||||
users: user._count,
|
||||
storage: file._sum.size!,
|
||||
storage: Number(file._sum.size!),
|
||||
|
||||
fileViews: file._sum.views!,
|
||||
fileViews: Number(file._sum.views!),
|
||||
urlViews: url._sum.views!,
|
||||
|
||||
filesUsers: filesByUser.map((x) => ({
|
||||
username: x.userId!,
|
||||
sum: x._count,
|
||||
storage: x._sum.size!,
|
||||
storage: Number(x._sum.size!),
|
||||
views: x._sum.views!,
|
||||
})),
|
||||
urlsUsers: urlsByUser.map((x) => ({ username: x.userId!, sum: x._count, views: x._sum.views! })),
|
||||
|
||||
@@ -80,8 +80,8 @@ export async function handler(req: NextApiReq, res: NextApiRes<ApiUserStatsRespo
|
||||
favoriteFiles: favCount ?? 0,
|
||||
views: aggFile._sum.views ?? 0,
|
||||
avgViews: aggFile._avg.views ?? 0,
|
||||
storageUsed: aggFile._sum.size ?? 0,
|
||||
avgStorageUsed: aggFile._avg.size ?? 0,
|
||||
storageUsed: Number(aggFile._sum.size ?? 0),
|
||||
avgStorageUsed: Number(aggFile._avg.size ?? 0),
|
||||
urlsCreated: aggUrl._count._all ?? 0,
|
||||
urlViews: aggUrl._sum.views ?? 0,
|
||||
|
||||
|
||||
@@ -25,6 +25,16 @@ const MODE = process.env.NODE_ENV || 'production';
|
||||
const logger = log('server');
|
||||
const scheduler = new Scheduler();
|
||||
|
||||
declare global {
|
||||
interface BigInt {
|
||||
toJSON(): number;
|
||||
}
|
||||
}
|
||||
|
||||
BigInt.prototype.toJSON = function () {
|
||||
return Number(this.toString());
|
||||
};
|
||||
|
||||
async function main() {
|
||||
logger.info('starting zipline', { mode: MODE, version: version });
|
||||
|
||||
|
||||
Reference in New Issue
Block a user