feat: updates & bigint

This commit is contained in:
diced
2023-11-30 22:10:34 -08:00
parent a3faee5b57
commit 3a01c6462f
12 changed files with 952 additions and 1678 deletions

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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?

View File

@@ -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);

View File

@@ -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'>

View File

@@ -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,

View File

@@ -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[]':

View File

@@ -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 },

View File

@@ -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);
};

View File

@@ -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! })),

View File

@@ -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,

View File

@@ -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 });