Compare commits
41 Commits
834900f9bb
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| f9769ca79c | |||
| 06e01b42e6 | |||
| cfa823a390 | |||
| 2204e957e1 | |||
| 07aa4ff6b5 | |||
| 0b0039ce01 | |||
| d84496aad6 | |||
| 935331e825 | |||
| 58e3fb73b1 | |||
| a1fc19b202 | |||
| b6f1b6f3e4 | |||
| 80730ab549 | |||
| f37f781d4e | |||
| 8748a1d978 | |||
| 30b4f65ec6 | |||
| 678d1e7b5e | |||
| 9146a0c340 | |||
| 9a37330ede | |||
| 1893b8b371 | |||
| 3b7c18a984 | |||
| 81004f59d2 | |||
| fc04f7ba7a | |||
| d4040322a5 | |||
| 9b6be363a0 | |||
| 68512ff2d3 | |||
| b78708d2dd | |||
| f9e22626c4 | |||
| e425b7bc6b | |||
| ca514247a8 | |||
| be6ffbe551 | |||
| 6a563f7d7c | |||
| 2dacc47801 | |||
| 95b3ce9e29 | |||
| eac6e307f4 | |||
| ec357bb9fa | |||
| 86a5ed382a | |||
| e4d1d2fad5 | |||
| 1975759c0b | |||
| 463fd1c9b8 | |||
| 4a2d8b2b3d | |||
| 0cfa09de42 |
7
.dockerignore
Normal file
7
.dockerignore
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Dockerfile
|
||||||
|
.dockerignore
|
||||||
|
node_modules
|
||||||
|
npm-debug.log
|
||||||
|
README.md
|
||||||
|
.next
|
||||||
|
.git
|
||||||
18
.github/workflows/cron.yml
vendored
Normal file
18
.github/workflows/cron.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
name: Daily Cron (Make New DailyStats Document)
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: "0 0 * * *"
|
||||||
|
jobs:
|
||||||
|
cron:
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
steps:
|
||||||
|
- name: Install curl
|
||||||
|
run: apk add --no-cache curl
|
||||||
|
|
||||||
|
- name: Daily cron job | Create new dailyStats document.
|
||||||
|
run: |
|
||||||
|
curl --request POST \
|
||||||
|
--url 'https://bot-stats.lucids-cove.duckdns.org/api/graphql' \
|
||||||
|
--header 'x-api-key: ${{ secrets.NEXT_PUBLIC_API_TOKEN }}' \
|
||||||
|
--header 'Content-Type: application/json' \
|
||||||
|
--data '{ "query": "mutation Cron { cronJob ( mutationKey: \"${{ secrets.GRAPHQL_MUTATION_KEY }}\" ) { commandResponses createdAt linksDeleted timesTriggered updatedAt } }" }' \
|
||||||
71
.github/workflows/main.yml
vendored
Normal file
71
.github/workflows/main.yml
vendored
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
name: Main
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
env:
|
||||||
|
REGISTRY: gitea.lucids-cove.duckdns.org
|
||||||
|
OWNER: wkc
|
||||||
|
IMAGE_NAME: no-twitter-bot-stats
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-push-docker-image:
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
node-version: [20.x]
|
||||||
|
steps:
|
||||||
|
- name: "Base requirements"
|
||||||
|
run: |
|
||||||
|
# packages
|
||||||
|
apk update && apk add --no-cache git docker docker-compose nodejs gpg openssh npm ansible
|
||||||
|
# ansible collections
|
||||||
|
ansible-galaxy collection install community.general --force
|
||||||
|
ansible-galaxy collection install ansible.posix --force
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Enable Corepack
|
||||||
|
run: npm install -g corepack && corepack enable
|
||||||
|
- name: Log into registry ${{ env.REGISTRY }}
|
||||||
|
uses: docker/login-action@v2
|
||||||
|
with:
|
||||||
|
registry: ${{ env.REGISTRY }}
|
||||||
|
username: ${{ env.OWNER }}
|
||||||
|
password: ${{ secrets.TOKEN }}
|
||||||
|
- name: Docker Hub Login
|
||||||
|
run: echo "${{ secrets.DOCKER_HUB_TOKEN }}" | docker login -u "${{ secrets.DOCKER_HUB_USERNAME }}" --password-stdin
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v2
|
||||||
|
- name: Setup Docker buildx
|
||||||
|
uses: docker/setup-buildx-action@v2
|
||||||
|
- name: Extract Docker metadata
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v4
|
||||||
|
with:
|
||||||
|
images: ${{ env.REGISTRY }}/${{ env.OWNER }}/${{ env.IMAGE_NAME }}
|
||||||
|
- name: Build and Push Versioned Docker Image
|
||||||
|
id: build-and-push
|
||||||
|
uses: docker/build-push-action@v4
|
||||||
|
if: ${{ github.ref != 'refs/heads/main' }}
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: ${{ !github.event.pull_request.head.repo.fork }}
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
build-args: |
|
||||||
|
DATABASE_URL=${{ secrets.DATABASE_URL }}
|
||||||
|
NEXT_PUBLIC_API_TOKEN=${{ secrets.NEXT_PUBLIC_API_TOKEN }}
|
||||||
|
NEXT_PUBLIC_GRAPHQL_URL=${{ secrets.NEXT_PUBLIC_GRAPHQL_URL }}
|
||||||
|
- name: Build and Push Latest Docker Image
|
||||||
|
id: build-and-push-latest
|
||||||
|
uses: docker/build-push-action@v4
|
||||||
|
if: ${{ github.ref == 'refs/heads/main' }}
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: true
|
||||||
|
tags: ${{ env.REGISTRY }}/${{ env.OWNER }}/${{ env.IMAGE_NAME }}:latest
|
||||||
|
build-args: |
|
||||||
|
DATABASE_URL=${{ secrets.DATABASE_URL }}
|
||||||
|
NEXT_PUBLIC_API_TOKEN=${{ secrets.NEXT_PUBLIC_API_TOKEN }}
|
||||||
|
NEXT_PUBLIC_GRAPHQL_URL=${{ secrets.NEXT_PUBLIC_GRAPHQL_URL }}
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -40,4 +40,4 @@ yarn-error.log*
|
|||||||
*.tsbuildinfo
|
*.tsbuildinfo
|
||||||
next-env.d.ts
|
next-env.d.ts
|
||||||
|
|
||||||
/generated/prisma
|
/src/prisma/generated
|
||||||
|
|||||||
49
Dockerfile
Normal file
49
Dockerfile
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
# --- Stage 1: Dependencies ---
|
||||||
|
FROM node:20-alpine AS dependencies
|
||||||
|
RUN corepack enable
|
||||||
|
RUN corepack prepare yarn@stable --activate
|
||||||
|
WORKDIR /app
|
||||||
|
COPY package.json yarn.lock .yarnrc.yml ./
|
||||||
|
RUN yarn install
|
||||||
|
|
||||||
|
# --- Stage 2: Builder ---
|
||||||
|
FROM node:20-alpine AS builder
|
||||||
|
RUN corepack enable
|
||||||
|
RUN corepack prepare yarn@stable --activate
|
||||||
|
ARG DATABASE_URL
|
||||||
|
ENV DATABASE_URL=${DATABASE_URL}
|
||||||
|
ENV DATABASE_URL=${DATABASE_URL}
|
||||||
|
ARG NEXT_PUBLIC_GRAPHQL_URL
|
||||||
|
ENV NEXT_PUBLIC_GRAPHQL_URL=${NEXT_PUBLIC_GRAPHQL_URL}
|
||||||
|
ARG NEXT_PUBLIC_API_TOKEN
|
||||||
|
ENV NEXT_PUBLIC_API_TOKEN=${NEXT_PUBLIC_API_TOKEN}
|
||||||
|
RUN corepack enable
|
||||||
|
RUN corepack prepare yarn@stable --activate
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=dependencies /app/node_modules ./node_modules
|
||||||
|
COPY . ./
|
||||||
|
RUN yarn prisma-gen
|
||||||
|
RUN yarn build
|
||||||
|
|
||||||
|
# --- Stage 3: Runner ---
|
||||||
|
FROM node:20-alpine AS runner
|
||||||
|
RUN corepack enable
|
||||||
|
RUN corepack prepare yarn@stable --activate
|
||||||
|
ARG DATABASE_URL
|
||||||
|
ENV DATABASE_URL=${DATABASE_URL}
|
||||||
|
ARG NEXT_PUBLIC_GRAPHQL_URL
|
||||||
|
ENV NEXT_PUBLIC_GRAPHQL_URL=${NEXT_PUBLIC_GRAPHQL_URL}
|
||||||
|
ARG NEXT_PUBLIC_API_TOKEN
|
||||||
|
ENV NEXT_PUBLIC_API_TOKEN=${NEXT_PUBLIC_API_TOKEN}
|
||||||
|
RUN corepack enable
|
||||||
|
RUN corepack prepare yarn@stable --activate
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=dependencies /app/node_modules ./node_modules
|
||||||
|
COPY --from=builder /app/src/prisma/generated ./src/prisma/generated
|
||||||
|
COPY --from=builder /app/.next ./.next
|
||||||
|
COPY --from=builder /app/.yarn ./.yarn
|
||||||
|
COPY . ./
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
CMD ["yarn", "start"]
|
||||||
12
compose.override.yml
Normal file
12
compose.override.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
services:
|
||||||
|
no-twitter-bot:
|
||||||
|
image: gitea.lucids-cove.duckdns.org/wkc/no-twitter-bot-stats:latest
|
||||||
|
container_name: no-twitter-bot-stats
|
||||||
|
environment:
|
||||||
|
- DATABASE_URL=${DATABASE_URL}
|
||||||
|
- NEXT_PUBLIC_GRAPHQL_URL=${GRAPHQL_URL}
|
||||||
|
ports:
|
||||||
|
- "3000:80"
|
||||||
|
volumes:
|
||||||
|
- ".:/usr/src"
|
||||||
|
command: npm run dev
|
||||||
10
compose.prod.yml
Normal file
10
compose.prod.yml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
services:
|
||||||
|
no-twitter-bot:
|
||||||
|
image: gitea.lucids-cove.duckdns.org/wkc/no-twitter-bot-stats:latest
|
||||||
|
container_name: no-twitter-bot-stats
|
||||||
|
# env_file: stack.env
|
||||||
|
environment:
|
||||||
|
- DATABASE_URL=${DATABASE_URL}
|
||||||
|
- NEXT_PUBLIC_GRAPHQL_URL=${GRAPHQL_URL}
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
10
compose.yml
Normal file
10
compose.yml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
services:
|
||||||
|
no-twitter-bot:
|
||||||
|
image: gitea.lucids-cove.duckdns.org/wkc/no-twitter-bot-stats:latest
|
||||||
|
container_name: no-twitter-bot-stats
|
||||||
|
# env_file: stack.env
|
||||||
|
environment:
|
||||||
|
- DATABASE_URL=${DATABASE_URL}
|
||||||
|
- NEXT_PUBLIC_GRAPHQL_URL=${GRAPHQL_URL}
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
35
package.json
35
package.json
@@ -8,48 +8,51 @@
|
|||||||
"start": "next start",
|
"start": "next start",
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
"pretty": "prettier --write .",
|
"pretty": "prettier --write .",
|
||||||
"prsima": "yarn prisma generate",
|
"prisma-gen": "yarn prisma generate",
|
||||||
"update-db": "yarn prisma db push"
|
"prisma-update": "yarn prisma db push"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@chakra-ui/react": "^3.29.0",
|
"@chakra-ui/charts": "^3.30.0",
|
||||||
|
"@chakra-ui/react": "^3.30.0",
|
||||||
"@emotion/react": "^11.14.0",
|
"@emotion/react": "^11.14.0",
|
||||||
|
"@escape.tech/graphql-armor": "^3.1.7",
|
||||||
"@prisma/client": "^6.19.0",
|
"@prisma/client": "^6.19.0",
|
||||||
"@prisma/extension-accelerate": "^2.0.2",
|
"@prisma/extension-accelerate": "^2.0.2",
|
||||||
"@urql/next": "^2.0.0",
|
"@urql/next": "^2.0.0",
|
||||||
"dotenv": "^17.2.3",
|
"dotenv": "^17.2.3",
|
||||||
"graphql": "^16.12.0",
|
"graphql": "^16.12.0",
|
||||||
"graphql-scalars": "^1.25.0",
|
"graphql-scalars": "^1.25.0",
|
||||||
"graphql-yoga": "^5.16.2",
|
"graphql-yoga": "^5.17.1",
|
||||||
"next": "16.0.1",
|
"next": "16.0.7",
|
||||||
"next-themes": "^0.4.6",
|
"next-themes": "^0.4.6",
|
||||||
"react": "19.2.0",
|
"react": "19.2.1",
|
||||||
"react-dom": "19.2.0",
|
"react-dom": "19.2.1",
|
||||||
"react-icons": "^5.5.0",
|
"react-icons": "^5.5.0",
|
||||||
|
"recharts": "^3.5.1",
|
||||||
"rxjs": "^7.8.2",
|
"rxjs": "^7.8.2",
|
||||||
"urql": "^5.0.1"
|
"urql": "^5.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/eslintrc": "^3.3.1",
|
"@eslint/eslintrc": "^3.3.3",
|
||||||
"@eslint/js": "^9.39.1",
|
"@eslint/js": "^9.39.1",
|
||||||
"@iconify/react": "^6.0.2",
|
"@iconify/react": "^6.0.2",
|
||||||
"@types/node": "^24.10.1",
|
"@types/node": "^24.10.1",
|
||||||
"@types/react": "^19.2.3",
|
"@types/react": "^19.2.7",
|
||||||
"@types/react-dom": "^19.2.2",
|
"@types/react-dom": "^19.2.3",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.46.4",
|
"@typescript-eslint/eslint-plugin": "^8.48.1",
|
||||||
"@typescript-eslint/parser": "^8.46.4",
|
"@typescript-eslint/parser": "^8.48.1",
|
||||||
"eslint": "^9.39.1",
|
"eslint": "^9.39.1",
|
||||||
"eslint-config-next": "16.0.1",
|
"eslint-config-next": "16.0.7",
|
||||||
"eslint-config-prettier": "^10.1.8",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"eslint-plugin-jsx-a11y": "^6.10.2",
|
"eslint-plugin-jsx-a11y": "^6.10.2",
|
||||||
"eslint-plugin-prettier": "^5.5.4",
|
"eslint-plugin-prettier": "^5.5.4",
|
||||||
"eslint-plugin-react": "^7.37.5",
|
"eslint-plugin-react": "^7.37.5",
|
||||||
"eslint-plugin-react-hooks": "^7.0.1",
|
"eslint-plugin-react-hooks": "^7.0.1",
|
||||||
"prettier": "3.6.2",
|
"prettier": "3.7.4",
|
||||||
"prisma": "^6.19.0",
|
"prisma": "^6.19.0",
|
||||||
"tsx": "^4.20.6",
|
"tsx": "^4.21.0",
|
||||||
"typescript": "^5.9.3",
|
"typescript": "^5.9.3",
|
||||||
"typescript-eslint": "^8.46.4"
|
"typescript-eslint": "^8.48.1"
|
||||||
},
|
},
|
||||||
"packageManager": "yarn@4.11.0"
|
"packageManager": "yarn@4.11.0"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
<svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>
|
|
||||||
|
Before Width: | Height: | Size: 391 B |
@@ -1 +0,0 @@
|
|||||||
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.0 KiB |
13
public/images/SPD-arrows.svg
Normal file
13
public/images/SPD-arrows.svg
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<svg
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
width="409.96661"
|
||||||
|
height="409.98404"
|
||||||
|
viewBox="0 0 409.96661 409.98404"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="m 198.43447,409.88349 c -16.87402,-0.52429 -33.96148,-3.20112 -50.15064,-7.85635 -16.89988,-4.85959 -33.4194,-12.04085 -48.45,-21.06187 C 89.057412,374.49751 79.188152,367.3017 69.836023,359.09346 63.443873,353.48316 56.486693,346.52267 50.841584,340.09001 23.882655,309.37001 6.733496,271.34323 1.6401223,230.99002 -3.0267695,194.01569 2.3071672,156.75191 17.114155,122.88582 c 2.83776,-6.49044 6.63732,-14.00102 10.21694,-20.1958 C 42.991144,75.589277 64.616853,52.405411 90.533832,34.933461 108.33243,22.934523 127.85299,13.821763 148.38383,7.9274153 c 26.15516,-7.50907673 53.79077,-9.7183097 81.05,-6.4792629 50.21751,5.9670387 96.51852,30.4672236 130.00448,68.7918786 26.75943,30.626139 43.81786,68.571209 48.88922,108.749989 4.86563,38.54882 -1.15232,77.44493 -17.37657,112.31081 -8.98481,19.30835 -20.76424,36.8569 -35.46819,52.83918 -2.44277,2.65514 -8.7281,8.94409 -11.35114,11.35768 -14.70283,13.5288 -30.43046,24.37645 -48.03196,33.12859 -4.05332,2.01546 -5.5776,2.72668 -9.56585,4.46335 -27.56473,12.00295 -57.65906,17.73965 -88.09935,16.79386 z m 13.44936,-34.9928 c 25.01212,-1.07439 48.36413,-7.17806 70.34385,-18.38623 19.2632,-9.82294 36.50092,-23.26822 50.87783,-39.6843 7.86352,-8.97886 15.0508,-19.24676 20.93747,-29.91169 1.47754,-2.67687 4.04205,-7.75113 5.39976,-10.6842 8.41325,-18.17525 13.5806,-38.08598 15.08733,-58.13425 0.35814,-4.76539 0.40375,-6.24526 0.40375,-13.1 0,-7.80507 -0.13553,-10.87819 -0.75413,-17.1 -3.3773,-33.96857 -16.9036,-65.97946 -39.00164,-92.299992 -4.83753,-5.76189 -10.83367,-11.955826 -16.62603,-17.174494 -16.89903,-15.22529 -37.39974,-27.226947 -58.91819,-34.492262 -15.49468,-5.231496 -31.10132,-8.118781 -47.75,-8.833924 -2.89874,-0.124515 -10.90126,-0.124515 -13.8,0 -16.64507,0.714988 -32.25869,3.603565 -47.75,8.833924 -22.42114,7.57009 -43.37752,20.065402 -60.949998,36.341643 -2.01749,1.868667 -6.68465,6.525563 -8.64412,8.625113 -18.522729,19.846862 -31.943938,43.538062 -39.299728,69.372092 -3.13635,11.01509 -5.12484,22.15786 -6.00108,33.6279 -0.35666,4.6688 -0.40507,6.2343 -0.40507,13.1 0,6.8657 0.04841,8.4312 0.40507,13.1 1.22839,16.0797 4.67357,31.67931 10.32477,46.75 5.59407,14.91838 13.591089,29.46979 23.231919,42.27293 12.532319,16.64308 28.020458,30.89004 45.549847,41.8996 16.73723,10.51204 34.82788,17.91208 54.08839,22.12504 9.16278,2.00422 19.45487,3.32848 29.1,3.74422 2.65778,0.11456 11.5597,0.12015 14.15,0.009 z m -37.2,-46.83768 v -30.8126 l 9.28842,9.28802 9.28842,9.28802 76.72486,-76.72488 76.72486,-76.72488 12.28672,12.28673 12.28673,12.28673 -76.64997,76.64993 c -42.15747,42.15746 -76.64998,76.71734 -76.65,76.79973 -2e-5,0.0824 4.12343,4.27345 9.16323,9.31347 l 9.16327,9.16368 -30.81327,-0.001 -30.81327,-10e-4 v -30.81259 z m -61.7,-31.04633 c -0.0664,-0.0221 -0.1,-10.37788 -0.1,-30.79993 v -30.7666 l 9.2544,9.2544 9.2544,9.2544 76.72511,-76.72511 76.7251,-76.72511 12.29318,12.29349 12.29318,12.29349 -76.64567,76.64613 c -42.15513,42.15537 -76.66344,76.6994 -76.68514,76.7645 -0.0217,0.0651 4.0948,4.25282 9.14779,9.30603 5.05298,5.0532 9.16483,9.1914 9.13745,9.19599 -0.1628,0.0273 -61.31804,0.0356 -61.3998,0.008 z M 51.026084,235.09894 c -0.02324,-0.0232 -0.04225,-13.88347 -0.04225,-30.80052 v -30.75827 l 9.266339,9.26634 9.26633,9.26634 76.638487,-76.63848 c 42.15116,-42.151155 76.68658,-76.668199 76.74537,-76.704532 0.06,-0.03707 5.49452,5.321436 12.38275,12.209497 l 12.27587,12.275559 -76.68758,76.687446 c -42.17816,42.1781 -76.687569,76.72116 -76.687569,76.76237 0,0.0412 4.140059,4.21517 9.200129,9.27546 l 9.20013,9.20054 H 81.826212 c -16.916829,0 -30.776888,-0.0188 -30.800128,-0.042 z"
|
||||||
|
id="path3338"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 3.7 KiB |
@@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.3 KiB |
@@ -1 +0,0 @@
|
|||||||
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>
|
|
||||||
|
Before Width: | Height: | Size: 128 B |
@@ -1 +0,0 @@
|
|||||||
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>
|
|
||||||
|
Before Width: | Height: | Size: 385 B |
21
src/app/CommandResponsesChart.tsx
Normal file
21
src/app/CommandResponsesChart.tsx
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { JSX } from "react";
|
||||||
|
import { Heading, VStack } from "@chakra-ui/react";
|
||||||
|
import LineChartComponent from "@/components/charts/LineChart";
|
||||||
|
import { LineChartArr } from "@/types/LineChartStats";
|
||||||
|
|
||||||
|
interface CommandResponsesChartProps {
|
||||||
|
lineChartData: LineChartArr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CommandResponsesChart = ({
|
||||||
|
lineChartData
|
||||||
|
}: CommandResponsesChartProps): JSX.Element => {
|
||||||
|
return (
|
||||||
|
<VStack gap={6} w="100%">
|
||||||
|
<Heading as="h4" fontSize="2xl">{`Commands Responded To`}</Heading>
|
||||||
|
<LineChartComponent data={lineChartData} label="Command Responses" />
|
||||||
|
</VStack>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CommandResponsesChart;
|
||||||
21
src/app/LinksDeletedChart.tsx
Normal file
21
src/app/LinksDeletedChart.tsx
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { JSX } from "react";
|
||||||
|
import { Heading, VStack } from "@chakra-ui/react";
|
||||||
|
import LineChartComponent from "@/components/charts/LineChart";
|
||||||
|
import { LineChartArr } from "@/types/LineChartStats";
|
||||||
|
|
||||||
|
interface LinksDeletedChartProps {
|
||||||
|
lineChartData: LineChartArr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LinksDeletedChart = ({
|
||||||
|
lineChartData
|
||||||
|
}: LinksDeletedChartProps): JSX.Element => {
|
||||||
|
return (
|
||||||
|
<VStack gap={6} w="100%">
|
||||||
|
<Heading as="h4" fontSize="2xl">{`Links Deleted`}</Heading>
|
||||||
|
<LineChartComponent data={lineChartData} label="Links Deleted" />
|
||||||
|
</VStack>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LinksDeletedChart;
|
||||||
73
src/app/StatsList.tsx
Normal file
73
src/app/StatsList.tsx
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
import { JSX } from "react";
|
||||||
|
import { Heading, Flex, Text, VStack } from "@chakra-ui/react";
|
||||||
|
import { CombinedError } from "urql";
|
||||||
|
import SingleStatComponent from "@/components/stats/SingleStat";
|
||||||
|
|
||||||
|
interface StatsListProps {
|
||||||
|
title: string;
|
||||||
|
loading: boolean;
|
||||||
|
error: CombinedError | undefined;
|
||||||
|
groups?: number;
|
||||||
|
links: number;
|
||||||
|
commands: number;
|
||||||
|
triggers: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const StatsList = ({
|
||||||
|
title,
|
||||||
|
loading,
|
||||||
|
error,
|
||||||
|
groups,
|
||||||
|
commands,
|
||||||
|
links,
|
||||||
|
triggers
|
||||||
|
}: StatsListProps): JSX.Element => {
|
||||||
|
return (
|
||||||
|
<VStack gap={6} w="100%">
|
||||||
|
<VStack gap={1}>
|
||||||
|
<Heading as="h3" fontSize="3xl">
|
||||||
|
{title}
|
||||||
|
</Heading>
|
||||||
|
<Text textAlign="center" fontSize="sm" color="whiteAlpha.800">
|
||||||
|
{groups !== undefined
|
||||||
|
? groups >= 0
|
||||||
|
? "Updates every 24 hours"
|
||||||
|
: ""
|
||||||
|
: "At time of page load"}
|
||||||
|
</Text>
|
||||||
|
</VStack>
|
||||||
|
<Flex w="80%" flexDirection={{ base: "column", md: "row" }} gap={4}>
|
||||||
|
{groups !== undefined ? (
|
||||||
|
groups >= 0 ? (
|
||||||
|
<SingleStatComponent
|
||||||
|
loading={loading}
|
||||||
|
title="Groups Bot Helped"
|
||||||
|
error={error}
|
||||||
|
stat={groups}
|
||||||
|
/>
|
||||||
|
) : null
|
||||||
|
) : null}
|
||||||
|
<SingleStatComponent
|
||||||
|
loading={loading}
|
||||||
|
title="Links Deleted"
|
||||||
|
error={error}
|
||||||
|
stat={links}
|
||||||
|
/>
|
||||||
|
<SingleStatComponent
|
||||||
|
loading={loading}
|
||||||
|
title="Commands Responded To"
|
||||||
|
error={error}
|
||||||
|
stat={commands}
|
||||||
|
/>
|
||||||
|
<SingleStatComponent
|
||||||
|
loading={loading}
|
||||||
|
title="Times Triggered"
|
||||||
|
error={error}
|
||||||
|
stat={triggers}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
</VStack>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default StatsList;
|
||||||
21
src/app/TimesTriggeredChart.tsx
Normal file
21
src/app/TimesTriggeredChart.tsx
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { JSX } from "react";
|
||||||
|
import LineChartComponent from "@/components/charts/LineChart";
|
||||||
|
import { LineChartArr } from "@/types/LineChartStats";
|
||||||
|
import { Heading, VStack } from "@chakra-ui/react";
|
||||||
|
|
||||||
|
interface TimedTriggeredChartProps {
|
||||||
|
lineChartData: LineChartArr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TimedTriggeredChart = ({
|
||||||
|
lineChartData
|
||||||
|
}: TimedTriggeredChartProps): JSX.Element => {
|
||||||
|
return (
|
||||||
|
<VStack gap={6} w="100%">
|
||||||
|
<Heading as="h4" fontSize="2xl">{`Times Bot Was Triggered`}</Heading>
|
||||||
|
<LineChartComponent data={lineChartData} label="Times Triggered" />
|
||||||
|
</VStack>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TimedTriggeredChart;
|
||||||
@@ -1,11 +1,54 @@
|
|||||||
|
/* eslint-disable react-hooks/rules-of-hooks */
|
||||||
|
import { createYoga, Plugin, createSchema } from "graphql-yoga";
|
||||||
|
import { EnvelopArmorPlugin } from "@escape.tech/graphql-armor";
|
||||||
import resolvers from "@/graphql/resolvers";
|
import resolvers from "@/graphql/resolvers";
|
||||||
import typeDefs from "@/graphql/types";
|
import typeDefs from "@/graphql/types";
|
||||||
import { createSchema, createYoga } from "graphql-yoga";
|
|
||||||
|
|
||||||
interface NextContext {
|
interface NextContext {
|
||||||
params: Promise<Record<string, string>>;
|
params: Promise<Record<string, string>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const environment = process.env.NODE_ENV || "development";
|
||||||
|
|
||||||
|
const isValidApiKey = (apiKey: string): boolean => {
|
||||||
|
const envApiKey =
|
||||||
|
process.env.API_TOKEN || process.env.NEXT_PUBLIC_API_TOKEN || "";
|
||||||
|
|
||||||
|
return apiKey === envApiKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
function useApiKey(): Plugin {
|
||||||
|
return {
|
||||||
|
async onRequest({ request, endResponse, fetchAPI }) {
|
||||||
|
const apiKey = await request.headers.get("x-api-key");
|
||||||
|
|
||||||
|
if (environment === "production") {
|
||||||
|
if (!apiKey || apiKey == null) {
|
||||||
|
endResponse(
|
||||||
|
new fetchAPI.Response(
|
||||||
|
JSON.stringify({
|
||||||
|
message: "No API Key provided"
|
||||||
|
}),
|
||||||
|
{ status: 401, headers: { "Content-Type": "application/json" } }
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (apiKey !== null && !(await isValidApiKey(apiKey))) {
|
||||||
|
endResponse(
|
||||||
|
new fetchAPI.Response(
|
||||||
|
JSON.stringify({
|
||||||
|
message: "Invalid API Key"
|
||||||
|
}),
|
||||||
|
{ status: 403, headers: { "Content-Type": "application/json" } }
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const { handleRequest } = createYoga<NextContext>({
|
const { handleRequest } = createYoga<NextContext>({
|
||||||
schema: createSchema({
|
schema: createSchema({
|
||||||
typeDefs: typeDefs,
|
typeDefs: typeDefs,
|
||||||
@@ -16,7 +59,10 @@ const { handleRequest } = createYoga<NextContext>({
|
|||||||
graphqlEndpoint: "/api/graphql",
|
graphqlEndpoint: "/api/graphql",
|
||||||
|
|
||||||
// Yoga needs to know how to create a valid Next response
|
// Yoga needs to know how to create a valid Next response
|
||||||
fetchAPI: { Response }
|
fetchAPI: { Response },
|
||||||
|
|
||||||
|
plugins: [useApiKey(), EnvelopArmorPlugin()],
|
||||||
|
graphiql: environment !== "production" ? true : false
|
||||||
});
|
});
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|||||||
@@ -20,16 +20,58 @@ export default function RootLayout({
|
|||||||
isClient: typeof window !== "undefined"
|
isClient: typeof window !== "undefined"
|
||||||
});
|
});
|
||||||
const client = createClient({
|
const client = createClient({
|
||||||
url: process.env.NEXT_PUBLIC_GRAPHQL_URL || "",
|
url: "/api/graphql",
|
||||||
exchanges: [cacheExchange, ssr, fetchExchange],
|
exchanges: [cacheExchange, ssr, fetchExchange],
|
||||||
suspense: true
|
suspense: true,
|
||||||
|
fetchOptions: {
|
||||||
|
headers: {
|
||||||
|
"x-api-key":
|
||||||
|
process.env?.API_TOKEN || process.env?.NEXT_PUBLIC_API_TOKEN || ""
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return [client, ssr];
|
return [client, ssr];
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const title = "Nazi Site Patrol Stats";
|
||||||
|
const description =
|
||||||
|
"A website to display various stats for the Nazi Site Patrol bot for Telegram. Developed and maintained by Werewolf Kid Creations.";
|
||||||
|
const url = "https://bot-stats.werewolfkid.monster";
|
||||||
|
const img = "/images/SPD-arrows.svg";
|
||||||
|
const domain = "werewolfkid.monster";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<html lang="en" suppressHydrationWarning>
|
<html lang="en" suppressHydrationWarning>
|
||||||
|
<title>{title}</title>
|
||||||
|
<meta name="description" content={description} />
|
||||||
|
<meta property="title" content={title} />
|
||||||
|
<meta name="theme-color" content="#00ffff" />
|
||||||
|
<link rel="icon" href={img} sizes="any" type="image/png" />
|
||||||
|
<meta property="image" content={img} />
|
||||||
|
<meta property="image:type" content="image/png" />
|
||||||
|
<meta property="image:width" content="653px" />
|
||||||
|
<meta property="og:title" content={title} />
|
||||||
|
<meta property="og:description" content={description} />
|
||||||
|
<meta property="og:url" content={url} />
|
||||||
|
<meta property="og:type" content="website" />
|
||||||
|
<meta property="og:image" content={img} />
|
||||||
|
<meta property="og:image:type" content="image/png" />
|
||||||
|
<meta property="og:image:width" content="653px" />
|
||||||
|
<meta property="og:image:height" content="651px" />
|
||||||
|
<meta property="image:height" content="651px" />
|
||||||
|
<meta name="twitter:title" content={title} />
|
||||||
|
<meta property="twitter:domain" content={domain} />
|
||||||
|
<meta property="twitter:url" content={url} />
|
||||||
|
<meta name="twitter:description" content={description} />
|
||||||
|
<meta name="twitter:image" content={img} />
|
||||||
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
|
<meta httpEquiv="content-language" content="en_US" />
|
||||||
|
<meta charSet="UTF-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href={img} />
|
||||||
|
<link rel="shortcut icon" href={img} />
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href={img} />
|
||||||
|
<link rel="manifest" href={img} />
|
||||||
<body>
|
<body>
|
||||||
<UrqlProvider client={client} ssr={ssr}>
|
<UrqlProvider client={client} ssr={ssr}>
|
||||||
<Provider>{children}</Provider>
|
<Provider>{children}</Provider>
|
||||||
|
|||||||
277
src/app/page.tsx
277
src/app/page.tsx
@@ -1,31 +1,268 @@
|
|||||||
|
/* eslint-disable react-hooks/set-state-in-effect */
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import GetTotalGroupsQuery from "@/graphql/queries/getTotalGroups";
|
import { Fragment, useEffect, useState } from "react";
|
||||||
import { Heading, Skeleton, Text } from "@chakra-ui/react";
|
import {
|
||||||
import { Icon } from "@iconify/react";
|
Box,
|
||||||
|
Button,
|
||||||
|
Heading,
|
||||||
|
Icon,
|
||||||
|
Link,
|
||||||
|
Skeleton,
|
||||||
|
Text,
|
||||||
|
VStack
|
||||||
|
} from "@chakra-ui/react";
|
||||||
import { useQuery } from "@urql/next";
|
import { useQuery } from "@urql/next";
|
||||||
import { Fragment } from "react/jsx-runtime";
|
import lineChartArr from "@/lib/lineChartArray";
|
||||||
|
import LinksDeletedChart from "./LinksDeletedChart";
|
||||||
|
import { LineChartArr } from "@/types/LineChartStats";
|
||||||
|
import CommandResponsesChart from "./CommandResponsesChart";
|
||||||
|
import TimedTriggeredChart from "./TimesTriggeredChart";
|
||||||
|
import StatsList from "./StatsList";
|
||||||
|
import GetTotalGroupsQuery from "@/graphql/queries/getTotalGroups";
|
||||||
|
import GetTotalStatsQuery from "@/graphql/queries/getTotalStats";
|
||||||
|
import GetTodaysStatsQuery from "@/graphql/queries/getTodaysStats";
|
||||||
|
import GetStatsRange from "@/graphql/queries/getStatsRange";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
const [{ fetching, data, error }] = useQuery({ query: GetTotalGroupsQuery });
|
// * Total Groups * //
|
||||||
|
|
||||||
|
const [
|
||||||
|
{
|
||||||
|
fetching: totalGroupsFetching,
|
||||||
|
data: totalGroups,
|
||||||
|
error: totalGroupsError
|
||||||
|
}
|
||||||
|
] = useQuery({
|
||||||
|
query: GetTotalGroupsQuery
|
||||||
|
});
|
||||||
|
|
||||||
|
// * Total Stats * //
|
||||||
|
|
||||||
|
const [
|
||||||
|
{ fetching: totalStatsFetching, data: totalStats, error: totalStatsError }
|
||||||
|
] = useQuery({
|
||||||
|
query: GetTotalStatsQuery
|
||||||
|
});
|
||||||
|
|
||||||
|
// * Today's Stats * //
|
||||||
|
|
||||||
|
const [
|
||||||
|
{ fetching: todaysStatsFetching, data: todayStats, error: todaysStatsError }
|
||||||
|
] = useQuery({
|
||||||
|
query: GetTodaysStatsQuery
|
||||||
|
});
|
||||||
|
|
||||||
|
// * 30 Day Stats * //
|
||||||
|
|
||||||
|
// Dates
|
||||||
|
const [currDate, setCurrDate] = useState<String>();
|
||||||
|
const [date30DaysAgo, setDate30DaysAgo] = useState<String>();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setCurrDate(new Date().toJSON());
|
||||||
|
setDate30DaysAgo(
|
||||||
|
new Date(new Date().setDate(new Date().getDay() - 30)).toJSON()
|
||||||
|
);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const [
|
||||||
|
{
|
||||||
|
fetching: thirtyDayStatsFetching,
|
||||||
|
data: thirtyDayStats,
|
||||||
|
error: thirtyDayStatsError
|
||||||
|
}
|
||||||
|
] = useQuery({
|
||||||
|
query: GetStatsRange,
|
||||||
|
variables: {
|
||||||
|
startDate: currDate || "",
|
||||||
|
endDate: date30DaysAgo || ""
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Line Chart Data
|
||||||
|
const [lineChartArrState, setLineChartArrState] = useState<LineChartArr>(
|
||||||
|
[] as LineChartArr
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!thirtyDayStatsFetching && thirtyDayStats && !thirtyDayStatsError) {
|
||||||
|
setLineChartArrState(lineChartArr(thirtyDayStats.getStatsRange));
|
||||||
|
}
|
||||||
|
}, [thirtyDayStats, thirtyDayStatsError, thirtyDayStatsFetching]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<Heading>{`Total number of groups the bot has helped`}</Heading>
|
<VStack bg="cyan.950" minH="100vh" h="100%" py="5vh" minW="fit-content">
|
||||||
<Skeleton loading={fetching} width="2rem">
|
<VStack w={{ base: "100%", md: "90%" }} gap={10} minW="fit-content">
|
||||||
<Text fontSize="2xl">
|
<VStack w="80%" gap={10}>
|
||||||
{error || !data || !data.getTotalGroups ? (
|
<Icon h="7.5rem" color="whiteAlpha">
|
||||||
<Icon
|
<svg
|
||||||
color="yellow"
|
id="svg2"
|
||||||
icon="solar:danger-triangle-broken"
|
version="1.1"
|
||||||
width="24"
|
width="409.96661"
|
||||||
height="24"
|
height="409.98404"
|
||||||
/>
|
viewBox="0 0 409.96661 409.98404"
|
||||||
) : (
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
`${data.getTotalGroups}`
|
>
|
||||||
)}
|
<g fill="currentColor">
|
||||||
</Text>
|
<path
|
||||||
</Skeleton>
|
d="m 198.43447,409.88349 c -16.87402,-0.52429 -33.96148,-3.20112 -50.15064,-7.85635 -16.89988,-4.85959 -33.4194,-12.04085 -48.45,-21.06187 C 89.057412,374.49751 79.188152,367.3017 69.836023,359.09346 63.443873,353.48316 56.486693,346.52267 50.841584,340.09001 23.882655,309.37001 6.733496,271.34323 1.6401223,230.99002 -3.0267695,194.01569 2.3071672,156.75191 17.114155,122.88582 c 2.83776,-6.49044 6.63732,-14.00102 10.21694,-20.1958 C 42.991144,75.589277 64.616853,52.405411 90.533832,34.933461 108.33243,22.934523 127.85299,13.821763 148.38383,7.9274153 c 26.15516,-7.50907673 53.79077,-9.7183097 81.05,-6.4792629 50.21751,5.9670387 96.51852,30.4672236 130.00448,68.7918786 26.75943,30.626139 43.81786,68.571209 48.88922,108.749989 4.86563,38.54882 -1.15232,77.44493 -17.37657,112.31081 -8.98481,19.30835 -20.76424,36.8569 -35.46819,52.83918 -2.44277,2.65514 -8.7281,8.94409 -11.35114,11.35768 -14.70283,13.5288 -30.43046,24.37645 -48.03196,33.12859 -4.05332,2.01546 -5.5776,2.72668 -9.56585,4.46335 -27.56473,12.00295 -57.65906,17.73965 -88.09935,16.79386 z m 13.44936,-34.9928 c 25.01212,-1.07439 48.36413,-7.17806 70.34385,-18.38623 19.2632,-9.82294 36.50092,-23.26822 50.87783,-39.6843 7.86352,-8.97886 15.0508,-19.24676 20.93747,-29.91169 1.47754,-2.67687 4.04205,-7.75113 5.39976,-10.6842 8.41325,-18.17525 13.5806,-38.08598 15.08733,-58.13425 0.35814,-4.76539 0.40375,-6.24526 0.40375,-13.1 0,-7.80507 -0.13553,-10.87819 -0.75413,-17.1 -3.3773,-33.96857 -16.9036,-65.97946 -39.00164,-92.299992 -4.83753,-5.76189 -10.83367,-11.955826 -16.62603,-17.174494 -16.89903,-15.22529 -37.39974,-27.226947 -58.91819,-34.492262 -15.49468,-5.231496 -31.10132,-8.118781 -47.75,-8.833924 -2.89874,-0.124515 -10.90126,-0.124515 -13.8,0 -16.64507,0.714988 -32.25869,3.603565 -47.75,8.833924 -22.42114,7.57009 -43.37752,20.065402 -60.949998,36.341643 -2.01749,1.868667 -6.68465,6.525563 -8.64412,8.625113 -18.522729,19.846862 -31.943938,43.538062 -39.299728,69.372092 -3.13635,11.01509 -5.12484,22.15786 -6.00108,33.6279 -0.35666,4.6688 -0.40507,6.2343 -0.40507,13.1 0,6.8657 0.04841,8.4312 0.40507,13.1 1.22839,16.0797 4.67357,31.67931 10.32477,46.75 5.59407,14.91838 13.591089,29.46979 23.231919,42.27293 12.532319,16.64308 28.020458,30.89004 45.549847,41.8996 16.73723,10.51204 34.82788,17.91208 54.08839,22.12504 9.16278,2.00422 19.45487,3.32848 29.1,3.74422 2.65778,0.11456 11.5597,0.12015 14.15,0.009 z m -37.2,-46.83768 v -30.8126 l 9.28842,9.28802 9.28842,9.28802 76.72486,-76.72488 76.72486,-76.72488 12.28672,12.28673 12.28673,12.28673 -76.64997,76.64993 c -42.15747,42.15746 -76.64998,76.71734 -76.65,76.79973 -2e-5,0.0824 4.12343,4.27345 9.16323,9.31347 l 9.16327,9.16368 -30.81327,-0.001 -30.81327,-10e-4 v -30.81259 z m -61.7,-31.04633 c -0.0664,-0.0221 -0.1,-10.37788 -0.1,-30.79993 v -30.7666 l 9.2544,9.2544 9.2544,9.2544 76.72511,-76.72511 76.7251,-76.72511 12.29318,12.29349 12.29318,12.29349 -76.64567,76.64613 c -42.15513,42.15537 -76.66344,76.6994 -76.68514,76.7645 -0.0217,0.0651 4.0948,4.25282 9.14779,9.30603 5.05298,5.0532 9.16483,9.1914 9.13745,9.19599 -0.1628,0.0273 -61.31804,0.0356 -61.3998,0.008 z M 51.026084,235.09894 c -0.02324,-0.0232 -0.04225,-13.88347 -0.04225,-30.80052 v -30.75827 l 9.266339,9.26634 9.26633,9.26634 76.638487,-76.63848 c 42.15116,-42.151155 76.68658,-76.668199 76.74537,-76.704532 0.06,-0.03707 5.49452,5.321436 12.38275,12.209497 l 12.27587,12.275559 -76.68758,76.687446 c -42.17816,42.1781 -76.687569,76.72116 -76.687569,76.76237 0,0.0412 4.140059,4.21517 9.200129,9.27546 l 9.20013,9.20054 H 81.826212 c -16.916829,0 -30.776888,-0.0188 -30.800128,-0.042 z"
|
||||||
|
id="path3338"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
</Icon>
|
||||||
|
<VStack gap={4} maxW="34rem">
|
||||||
|
<Heading as="h1" fontSize="5xl">
|
||||||
|
{"Anti Nazi Sites Bot Stats"}
|
||||||
|
</Heading>
|
||||||
|
<Heading
|
||||||
|
as="h2"
|
||||||
|
fontSize="xl"
|
||||||
|
color="whiteAlpha.800"
|
||||||
|
textAlign="center"
|
||||||
|
>
|
||||||
|
{
|
||||||
|
"A telegram bot that removes links and embeds to sites that align with the Fascist Right political agenda."
|
||||||
|
}
|
||||||
|
</Heading>
|
||||||
|
</VStack>
|
||||||
|
<VStack gap={0} w="min-content">
|
||||||
|
<Link target="_blank" href={`https://t.me/NoTwitter_Bot`}>
|
||||||
|
<Button variant="solid" bgColor={"teal.solid"} fontSize="xl">
|
||||||
|
{"Add the bot to your telegram group"}
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
<Text textAlign="center" fontSize="md" color="whiteAlpha.800">
|
||||||
|
{
|
||||||
|
"The bot requires no configuration. All it needs is admin privileges to delete messages in your group."
|
||||||
|
}
|
||||||
|
</Text>
|
||||||
|
</VStack>
|
||||||
|
</VStack>
|
||||||
|
<VStack gap={10} w="100%">
|
||||||
|
{totalGroups ? (
|
||||||
|
<StatsList
|
||||||
|
title="Total Stats"
|
||||||
|
loading={totalStatsFetching || totalGroupsFetching}
|
||||||
|
error={totalStatsError || totalGroupsError}
|
||||||
|
groups={totalGroups.getTotalGroups}
|
||||||
|
links={totalStats.getTotalStats.linksDeleted}
|
||||||
|
commands={totalStats.getTotalStats.commandResponses}
|
||||||
|
triggers={totalStats.getTotalStats.timesTriggered}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<StatsList
|
||||||
|
title="Total Stats"
|
||||||
|
loading={totalStatsFetching || totalGroupsFetching}
|
||||||
|
error={totalStatsError || totalGroupsError}
|
||||||
|
groups={0}
|
||||||
|
links={0}
|
||||||
|
commands={0}
|
||||||
|
triggers={0}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{todayStats ? (
|
||||||
|
<StatsList
|
||||||
|
title="Today's Stats"
|
||||||
|
loading={todaysStatsFetching}
|
||||||
|
error={todaysStatsError}
|
||||||
|
links={todayStats.getTodayStats.linksDeleted}
|
||||||
|
commands={todayStats.getTodayStats.commandResponses}
|
||||||
|
triggers={todayStats.getTodayStats.timesTriggered}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<StatsList
|
||||||
|
title="Today's Stats"
|
||||||
|
loading={todaysStatsFetching}
|
||||||
|
error={todaysStatsError}
|
||||||
|
links={0}
|
||||||
|
commands={0}
|
||||||
|
triggers={0}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</VStack>
|
||||||
|
<VStack w="95%" gap="5vh">
|
||||||
|
<VStack gap={1}>
|
||||||
|
<Heading as="h1" fontSize="3xl">{`30 Day Stats`}</Heading>
|
||||||
|
<Text textAlign="center" fontSize="sm" color="whiteAlpha.800">
|
||||||
|
{"Updates every 24 hours"}
|
||||||
|
</Text>
|
||||||
|
</VStack>
|
||||||
|
<Skeleton w="100%" h="auto" loading={thirtyDayStatsFetching}>
|
||||||
|
<LinksDeletedChart lineChartData={lineChartArrState} />
|
||||||
|
</Skeleton>
|
||||||
|
<Skeleton w="100%" h="auto" loading={thirtyDayStatsFetching}>
|
||||||
|
<CommandResponsesChart lineChartData={lineChartArrState} />
|
||||||
|
</Skeleton>
|
||||||
|
<Skeleton w="100%" h="auto" loading={thirtyDayStatsFetching}>
|
||||||
|
<TimedTriggeredChart lineChartData={lineChartArrState} />
|
||||||
|
</Skeleton>
|
||||||
|
</VStack>
|
||||||
|
</VStack>
|
||||||
|
</VStack>
|
||||||
|
<Box
|
||||||
|
bgImage={`linear-gradient(
|
||||||
|
to right,
|
||||||
|
rgb(85, 205, 252),
|
||||||
|
rgb(179, 157, 233),
|
||||||
|
rgb(247, 168, 184),
|
||||||
|
rgb(246, 216, 221),
|
||||||
|
rgb(255, 255, 255) 10%,
|
||||||
|
rgb(0, 0, 0),
|
||||||
|
rgb(54, 35, 18),
|
||||||
|
rgb(120, 79, 23),
|
||||||
|
rgb(181, 63, 27),
|
||||||
|
rgb(237, 34, 36),
|
||||||
|
rgb(243, 91, 34),
|
||||||
|
rgb(249, 150, 33),
|
||||||
|
rgb(245, 193, 30),
|
||||||
|
rgb(241, 235, 27) 48%,
|
||||||
|
rgb(241, 235, 27),
|
||||||
|
rgb(241, 235, 27) 52%,
|
||||||
|
rgb(99, 199, 32),
|
||||||
|
rgb(12, 155, 73),
|
||||||
|
rgb(33, 135, 141),
|
||||||
|
rgb(57, 84, 165),
|
||||||
|
rgb(97, 55, 155),
|
||||||
|
rgb(147, 40, 142)
|
||||||
|
)`}
|
||||||
|
w="100%"
|
||||||
|
py="5vh"
|
||||||
|
textAlign="center"
|
||||||
|
>
|
||||||
|
<VStack
|
||||||
|
color="white"
|
||||||
|
textShadow="0px 0px 5px black;"
|
||||||
|
WebkitTextStroke="0.3px black;"
|
||||||
|
gap={6}
|
||||||
|
w="100%"
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
fontSize="3xl"
|
||||||
|
minW="fit-content"
|
||||||
|
w={{ base: "100%", sm: "auto" }}
|
||||||
|
bg="blackAlpha.600"
|
||||||
|
maxW={{ base: "", sm: "62vw" }}
|
||||||
|
px={2}
|
||||||
|
>
|
||||||
|
{"Down with fascism! Fuck MAGA! Fuck Trump! Fuck Nazis!"}
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
fontSize="3xl"
|
||||||
|
minW="fit-content"
|
||||||
|
w={{ base: "100%", sm: "auto" }}
|
||||||
|
bg="blackAlpha.600"
|
||||||
|
maxW={{ base: "", sm: "62vw" }}
|
||||||
|
px={2}
|
||||||
|
>
|
||||||
|
{
|
||||||
|
"Trans rights are human rights! Trans women are women! Trans men are men! Never let them take away your happiness!"
|
||||||
|
}
|
||||||
|
</Text>
|
||||||
|
</VStack>
|
||||||
|
</Box>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
65
src/components/charts/LineChart.tsx
Normal file
65
src/components/charts/LineChart.tsx
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
import { JSX } from "react";
|
||||||
|
import { Chart, useChart } from "@chakra-ui/charts";
|
||||||
|
import {
|
||||||
|
CartesianGrid,
|
||||||
|
Line,
|
||||||
|
LineChart,
|
||||||
|
Tooltip,
|
||||||
|
XAxis,
|
||||||
|
YAxis
|
||||||
|
} from "recharts";
|
||||||
|
import { LineChartArr } from "@/types/LineChartStats";
|
||||||
|
|
||||||
|
interface LineChartComponentProps {
|
||||||
|
label: "Times Triggered" | "Links Deleted" | "Command Responses";
|
||||||
|
data: LineChartArr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LineChartComponent = ({
|
||||||
|
data,
|
||||||
|
label
|
||||||
|
}: LineChartComponentProps): JSX.Element => {
|
||||||
|
const chart = useChart({
|
||||||
|
data: [...data],
|
||||||
|
series: [{ name: label, color: "teal.500" }]
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Chart.Root maxH="xs" chart={chart} maxW="100vw">
|
||||||
|
<LineChart data={chart.data}>
|
||||||
|
<CartesianGrid stroke={chart.color("border")} vertical={false} />
|
||||||
|
<XAxis
|
||||||
|
axisLine={false}
|
||||||
|
dataKey={chart.key("day")}
|
||||||
|
stroke={chart.color("border")}
|
||||||
|
label={{ value: "Date", position: "bottom" }}
|
||||||
|
/>
|
||||||
|
<YAxis
|
||||||
|
width="auto"
|
||||||
|
axisLine={false}
|
||||||
|
tickLine={false}
|
||||||
|
tickMargin={10}
|
||||||
|
stroke={chart.color("border")}
|
||||||
|
// label={{ value: label, position: "left", angle: -90 }}
|
||||||
|
/>
|
||||||
|
<Tooltip
|
||||||
|
animationDuration={100}
|
||||||
|
cursor={false}
|
||||||
|
content={<Chart.Tooltip />}
|
||||||
|
/>
|
||||||
|
{chart.series.map((item) => (
|
||||||
|
<Line
|
||||||
|
key={item.name}
|
||||||
|
isAnimationActive={false}
|
||||||
|
dataKey={chart.key(item.name)}
|
||||||
|
stroke={chart.color(item.color)}
|
||||||
|
strokeWidth={2}
|
||||||
|
dot={false}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</LineChart>
|
||||||
|
</Chart.Root>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LineChartComponent;
|
||||||
44
src/components/stats/SingleStat.tsx
Normal file
44
src/components/stats/SingleStat.tsx
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import { JSX } from "react";
|
||||||
|
import { Skeleton, Stat, FormatNumber } from "@chakra-ui/react";
|
||||||
|
import { Icon } from "@iconify/react";
|
||||||
|
import { CombinedError } from "urql";
|
||||||
|
|
||||||
|
interface SingleStatComponentProps {
|
||||||
|
stat: number;
|
||||||
|
title: string;
|
||||||
|
loading: boolean;
|
||||||
|
error: CombinedError | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SingleStatComponent = ({
|
||||||
|
stat,
|
||||||
|
title,
|
||||||
|
loading,
|
||||||
|
error
|
||||||
|
}: SingleStatComponentProps): JSX.Element => {
|
||||||
|
return (
|
||||||
|
<Stat.Root alignItems="center">
|
||||||
|
<Stat.Label textAlign="center">{title}</Stat.Label>
|
||||||
|
<Stat.ValueText>
|
||||||
|
<Skeleton loading={loading} w="auto" minW="2.5rem" textAlign="center">
|
||||||
|
{(error || stat === undefined) && !loading ? (
|
||||||
|
<Icon
|
||||||
|
color="yellow"
|
||||||
|
icon="solar:danger-triangle-broken"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<FormatNumber
|
||||||
|
value={stat}
|
||||||
|
notation="compact"
|
||||||
|
compactDisplay="short"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Skeleton>
|
||||||
|
</Stat.ValueText>
|
||||||
|
</Stat.Root>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SingleStatComponent;
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
"use client";
|
|
||||||
|
|
||||||
import {
|
|
||||||
Toaster as ChakraToaster,
|
|
||||||
Portal,
|
|
||||||
Spinner,
|
|
||||||
Stack,
|
|
||||||
Toast,
|
|
||||||
createToaster
|
|
||||||
} from "@chakra-ui/react";
|
|
||||||
|
|
||||||
export const toaster = createToaster({
|
|
||||||
placement: "bottom-end",
|
|
||||||
pauseOnPageIdle: true
|
|
||||||
});
|
|
||||||
|
|
||||||
export const Toaster = () => {
|
|
||||||
return (
|
|
||||||
<Portal>
|
|
||||||
<ChakraToaster toaster={toaster} insetInline={{ mdDown: "4" }}>
|
|
||||||
{(toast) => (
|
|
||||||
<Toast.Root width={{ md: "sm" }}>
|
|
||||||
{toast.type === "loading" ? (
|
|
||||||
<Spinner size="sm" color="blue.solid" />
|
|
||||||
) : (
|
|
||||||
<Toast.Indicator />
|
|
||||||
)}
|
|
||||||
<Stack gap="1" flex="1" maxWidth="100%">
|
|
||||||
{toast.title && <Toast.Title>{toast.title}</Toast.Title>}
|
|
||||||
{toast.description && (
|
|
||||||
<Toast.Description>{toast.description}</Toast.Description>
|
|
||||||
)}
|
|
||||||
</Stack>
|
|
||||||
{toast.action && (
|
|
||||||
<Toast.ActionTrigger>{toast.action.label}</Toast.ActionTrigger>
|
|
||||||
)}
|
|
||||||
{toast.closable && <Toast.CloseTrigger />}
|
|
||||||
</Toast.Root>
|
|
||||||
)}
|
|
||||||
</ChakraToaster>
|
|
||||||
</Portal>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
import { Tooltip as ChakraTooltip, Portal } from "@chakra-ui/react";
|
|
||||||
import * as React from "react";
|
|
||||||
|
|
||||||
export interface TooltipProps extends ChakraTooltip.RootProps {
|
|
||||||
showArrow?: boolean;
|
|
||||||
portalled?: boolean;
|
|
||||||
portalRef?: React.RefObject<HTMLElement | null>;
|
|
||||||
content: React.ReactNode;
|
|
||||||
contentProps?: ChakraTooltip.ContentProps;
|
|
||||||
disabled?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const Tooltip = React.forwardRef<HTMLDivElement, TooltipProps>(
|
|
||||||
function Tooltip(props, ref) {
|
|
||||||
const {
|
|
||||||
showArrow,
|
|
||||||
children,
|
|
||||||
disabled,
|
|
||||||
portalled = true,
|
|
||||||
content,
|
|
||||||
contentProps,
|
|
||||||
portalRef,
|
|
||||||
...rest
|
|
||||||
} = props;
|
|
||||||
|
|
||||||
if (disabled) return children;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ChakraTooltip.Root {...rest}>
|
|
||||||
<ChakraTooltip.Trigger asChild>{children}</ChakraTooltip.Trigger>
|
|
||||||
<Portal disabled={!portalled} container={portalRef}>
|
|
||||||
<ChakraTooltip.Positioner>
|
|
||||||
<ChakraTooltip.Content ref={ref} {...contentProps}>
|
|
||||||
{showArrow && (
|
|
||||||
<ChakraTooltip.Arrow>
|
|
||||||
<ChakraTooltip.ArrowTip />
|
|
||||||
</ChakraTooltip.Arrow>
|
|
||||||
)}
|
|
||||||
{content}
|
|
||||||
</ChakraTooltip.Content>
|
|
||||||
</ChakraTooltip.Positioner>
|
|
||||||
</Portal>
|
|
||||||
</ChakraTooltip.Root>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
14
src/graphql/queries/getStatsRange.ts
Normal file
14
src/graphql/queries/getStatsRange.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { gql } from "@urql/next";
|
||||||
|
|
||||||
|
const GetStatsRange = gql`
|
||||||
|
query getStatsRange($startDate: String!, $endDate: String!) {
|
||||||
|
getStatsRange(endDate: $startDate, startDate: $endDate) {
|
||||||
|
commandResponses
|
||||||
|
createdAt
|
||||||
|
linksDeleted
|
||||||
|
timesTriggered
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default GetStatsRange;
|
||||||
13
src/graphql/queries/getTodaysStats.ts
Normal file
13
src/graphql/queries/getTodaysStats.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { gql } from "@urql/next";
|
||||||
|
|
||||||
|
const GetTodaysStatsQuery = gql`
|
||||||
|
query GetTodayStats {
|
||||||
|
getTodayStats {
|
||||||
|
commandResponses
|
||||||
|
linksDeleted
|
||||||
|
timesTriggered
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default GetTodaysStatsQuery;
|
||||||
13
src/graphql/queries/getTotalStats.ts
Normal file
13
src/graphql/queries/getTotalStats.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { gql } from "@urql/next";
|
||||||
|
|
||||||
|
const GetTotalStatsQuery = gql`
|
||||||
|
query GetTotalStats {
|
||||||
|
getTotalStats {
|
||||||
|
commandResponses
|
||||||
|
linksDeleted
|
||||||
|
timesTriggered
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default GetTotalStatsQuery;
|
||||||
@@ -1,6 +1,24 @@
|
|||||||
import prisma from "@/lib/prismaClient";
|
import prisma from "@/lib/prismaClient";
|
||||||
import { BigIntResolver } from "graphql-scalars";
|
import { BigIntResolver } from "graphql-scalars";
|
||||||
|
|
||||||
|
const envMutationKey = process.env.MUTATION_KEY || "";
|
||||||
|
const env = process.env.NODE_ENV || "development";
|
||||||
|
|
||||||
|
const isDailyStatToday = (date: string): boolean => {
|
||||||
|
const today = new Date().setHours(0, 0, 0, 0);
|
||||||
|
const dailyStatCreated = new Date(date).setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
|
return today == dailyStatCreated;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getLatestDailyStat = async () => {
|
||||||
|
return await prisma.dailyStats.findFirst({
|
||||||
|
orderBy: {
|
||||||
|
createdAt: "desc"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// Prisma
|
// Prisma
|
||||||
export const resolvers = {
|
export const resolvers = {
|
||||||
// scalars
|
// scalars
|
||||||
@@ -19,6 +37,11 @@ export const resolvers = {
|
|||||||
// _ctx: unknown
|
// _ctx: unknown
|
||||||
) => {
|
) => {
|
||||||
const { startDate, endDate } = data;
|
const { startDate, endDate } = data;
|
||||||
|
|
||||||
|
if (!startDate || !endDate) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return await prisma.dailyStats.findMany({
|
return await prisma.dailyStats.findMany({
|
||||||
where: {
|
where: {
|
||||||
createdAt: {
|
createdAt: {
|
||||||
@@ -36,109 +59,235 @@ export const resolvers = {
|
|||||||
orderBy: {
|
orderBy: {
|
||||||
createdAt: "asc"
|
createdAt: "asc"
|
||||||
}
|
}
|
||||||
|
}),
|
||||||
|
getGroupStats: async (
|
||||||
|
_parent: unknown,
|
||||||
|
data: { groupID: number }
|
||||||
|
// _ctx: unknown
|
||||||
|
) =>
|
||||||
|
await prisma.groups.findUnique({
|
||||||
|
where: {
|
||||||
|
telegramID: BigInt(data.groupID)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
Mutation: {
|
Mutation: {
|
||||||
init: async () =>
|
init: async (
|
||||||
// _parent: unknown,
|
|
||||||
// data: { newWeek: boolean; newMonth: boolean }
|
|
||||||
// _ctx: unknown
|
|
||||||
{
|
|
||||||
const date = new Date().toISOString();
|
|
||||||
let count = 0;
|
|
||||||
|
|
||||||
if ((await prisma.dailyStats.count()) === 0) {
|
|
||||||
await prisma.dailyStats.create({ data: { createdAt: date } });
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
if ((await prisma.totalStats.count()) === 0) {
|
|
||||||
await prisma.totalStats.create({ data: { createdAt: date } });
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return `${count} tables have been initialized with data.`;
|
|
||||||
},
|
|
||||||
cronJob: async () =>
|
|
||||||
// _parent: unknown,
|
|
||||||
// data: { newWeek: boolean; newMonth: boolean }
|
|
||||||
// _ctx: unknown
|
|
||||||
{
|
|
||||||
const date = new Date().toISOString();
|
|
||||||
|
|
||||||
await prisma.dailyStats.create({ data: { createdAt: date } });
|
|
||||||
|
|
||||||
const allStats = await prisma.dailyStats.findMany({});
|
|
||||||
|
|
||||||
const calculatedStats = allStats.reduce(
|
|
||||||
(acc, curr) => {
|
|
||||||
const links = (acc.linksDeleted += curr.linksDeleted);
|
|
||||||
const commands = (acc.commandResponses += curr.commandResponses);
|
|
||||||
const triggers = (acc.timesTriggered += curr.timesTriggered);
|
|
||||||
|
|
||||||
return {
|
|
||||||
linksDeleted: links,
|
|
||||||
commandResponses: commands,
|
|
||||||
timesTriggered: triggers
|
|
||||||
};
|
|
||||||
},
|
|
||||||
{
|
|
||||||
linksDeleted: 0,
|
|
||||||
commandResponses: 0,
|
|
||||||
timesTriggered: 0
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const totalStats = await prisma.totalStats.findFirst({
|
|
||||||
orderBy: {
|
|
||||||
createdAt: "desc"
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return await prisma.totalStats.update({
|
|
||||||
where: {
|
|
||||||
createdAt: totalStats?.createdAt
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
...calculatedStats
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
addGroup: async (
|
|
||||||
_parent: unknown,
|
_parent: unknown,
|
||||||
data: { groupID: number; groupName: string }
|
data: { mutationKey?: string }
|
||||||
// _ctx: unknown
|
// _ctx: unknown
|
||||||
) => {
|
) => {
|
||||||
const { groupID, groupName } = data;
|
const { mutationKey } = data;
|
||||||
|
|
||||||
|
if (env !== "development") {
|
||||||
|
if (!mutationKey) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mutationKey !== envMutationKey) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const date = new Date().toISOString();
|
||||||
|
let count = 0;
|
||||||
|
|
||||||
|
if ((await prisma.dailyStats.count()) === 0) {
|
||||||
|
await prisma.dailyStats.create({ data: { createdAt: date } });
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
if ((await prisma.totalStats.count()) === 0) {
|
||||||
|
await prisma.totalStats.create({ data: { createdAt: date } });
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${count} tables have been initialized with data.`;
|
||||||
|
},
|
||||||
|
cronJob: async (
|
||||||
|
_parent: unknown,
|
||||||
|
data: { mutationKey?: string }
|
||||||
|
// _ctx: unknown
|
||||||
|
) => {
|
||||||
|
const { mutationKey } = data;
|
||||||
|
|
||||||
|
if (env !== "development") {
|
||||||
|
if (!mutationKey) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mutationKey !== envMutationKey) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const latestDailyStats = await getLatestDailyStat();
|
||||||
|
|
||||||
|
if (latestDailyStats !== null) {
|
||||||
|
if (isDailyStatToday(String(latestDailyStats.createdAt))) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const date = new Date().toISOString();
|
||||||
|
|
||||||
|
await prisma.dailyStats.create({ data: { createdAt: date } });
|
||||||
|
|
||||||
|
const allStats = await prisma.dailyStats.findMany({});
|
||||||
|
|
||||||
|
const calculatedStats = allStats.reduce(
|
||||||
|
(acc, curr) => {
|
||||||
|
const links = (acc.linksDeleted += curr.linksDeleted);
|
||||||
|
const commands = (acc.commandResponses += curr.commandResponses);
|
||||||
|
const triggers = (acc.timesTriggered += curr.timesTriggered);
|
||||||
|
|
||||||
|
return {
|
||||||
|
linksDeleted: links,
|
||||||
|
commandResponses: commands,
|
||||||
|
timesTriggered: triggers
|
||||||
|
};
|
||||||
|
},
|
||||||
|
{
|
||||||
|
linksDeleted: 0,
|
||||||
|
commandResponses: 0,
|
||||||
|
timesTriggered: 0
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const totalStats = await prisma.totalStats.findFirst({
|
||||||
|
orderBy: {
|
||||||
|
createdAt: "desc"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return await prisma.totalStats.update({
|
||||||
|
where: {
|
||||||
|
createdAt: totalStats?.createdAt
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
...calculatedStats
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
addGroup: async (
|
||||||
|
_parent: unknown,
|
||||||
|
data: {
|
||||||
|
groupID: string;
|
||||||
|
groupName: string;
|
||||||
|
groupUsername: string;
|
||||||
|
mutationKey?: string;
|
||||||
|
}
|
||||||
|
// _ctx: unknown
|
||||||
|
) => {
|
||||||
|
const { groupID, groupName, groupUsername, mutationKey } = data;
|
||||||
|
const groupIDInt = BigInt(groupID);
|
||||||
|
|
||||||
|
if (env !== "development") {
|
||||||
|
if (!mutationKey) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mutationKey !== envMutationKey) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const existingGroup = await prisma.groups.findUnique({
|
||||||
|
where: { telegramID: groupIDInt }
|
||||||
|
});
|
||||||
|
|
||||||
|
if (existingGroup !== null) {
|
||||||
|
if (
|
||||||
|
existingGroup.name !== groupName ||
|
||||||
|
existingGroup.username !== groupUsername
|
||||||
|
) {
|
||||||
|
return await prisma.groups.update({
|
||||||
|
where: {
|
||||||
|
telegramID: existingGroup.telegramID
|
||||||
|
},
|
||||||
|
data: { name: groupName, username: groupUsername || "" }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return existingGroup;
|
||||||
|
}
|
||||||
|
|
||||||
return await prisma.groups.create({
|
return await prisma.groups.create({
|
||||||
data: {
|
data: {
|
||||||
telegramID: groupID,
|
telegramID: groupIDInt,
|
||||||
name: groupName
|
name: groupName
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
increment: async (
|
incrementGroup: async (
|
||||||
_parent: unknown,
|
_parent: unknown,
|
||||||
data: { link: boolean; command: boolean; trigger: boolean }
|
data: { groupID: number; linksDeleted: number; mutationKey?: string }
|
||||||
// _ctx: unknown
|
// _ctx: unknown
|
||||||
) => {
|
) => {
|
||||||
const { link, command, trigger } = data;
|
const { groupID, linksDeleted, mutationKey } = data;
|
||||||
|
|
||||||
return await prisma.dailyStats
|
if (env !== "development") {
|
||||||
.findFirst({
|
if (!mutationKey) {
|
||||||
orderBy: {
|
return null;
|
||||||
createdAt: "desc"
|
}
|
||||||
|
|
||||||
|
if (mutationKey !== envMutationKey) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return await prisma.groups.update({
|
||||||
|
where: { telegramID: BigInt(groupID) },
|
||||||
|
data: { linksDeleted: { increment: linksDeleted } }
|
||||||
|
});
|
||||||
|
},
|
||||||
|
increment: async (
|
||||||
|
_parent: unknown,
|
||||||
|
data: {
|
||||||
|
link: boolean;
|
||||||
|
command: boolean;
|
||||||
|
trigger: boolean;
|
||||||
|
mutationKey?: string;
|
||||||
|
}
|
||||||
|
// _ctx: unknown
|
||||||
|
) => {
|
||||||
|
const { link, command, trigger, mutationKey } = data;
|
||||||
|
|
||||||
|
if (env !== "development") {
|
||||||
|
if (!mutationKey) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mutationKey !== envMutationKey) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let latestDailyStats = await getLatestDailyStat();
|
||||||
|
|
||||||
|
if (latestDailyStats !== null) {
|
||||||
|
if (!isDailyStatToday(String(latestDailyStats.createdAt))) {
|
||||||
|
const date = new Date().toISOString();
|
||||||
|
|
||||||
|
await prisma.dailyStats
|
||||||
|
.create({ data: { createdAt: date } })
|
||||||
|
.then(async () => {
|
||||||
|
latestDailyStats = await prisma.dailyStats.findFirst({
|
||||||
|
orderBy: {
|
||||||
|
createdAt: "desc"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return await prisma.dailyStats.update({
|
||||||
|
where: { createdAt: latestDailyStats.createdAt },
|
||||||
|
data: {
|
||||||
|
linksDeleted: { increment: link ? 1 : 0 },
|
||||||
|
commandResponses: { increment: command ? 1 : 0 },
|
||||||
|
timesTriggered: { increment: trigger ? 1 : 0 }
|
||||||
}
|
}
|
||||||
})
|
|
||||||
.then(async (todayStat) => {
|
|
||||||
return await prisma.dailyStats.update({
|
|
||||||
where: { createdAt: todayStat?.createdAt },
|
|
||||||
data: {
|
|
||||||
linksDeleted: { increment: link ? 1 : 0 },
|
|
||||||
commandResponses: { increment: command ? 1 : 0 },
|
|
||||||
timesTriggered: { increment: trigger ? 1 : 0 }
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,19 +7,37 @@ const typeDefs = /* GraphQL */ `
|
|||||||
type Query {
|
type Query {
|
||||||
getTotalGroups: Int!
|
getTotalGroups: Int!
|
||||||
getTodayStats: DailyStats!
|
getTodayStats: DailyStats!
|
||||||
getStatsRange(startDate: Date, endDate: Date): [DailyStats]
|
getStatsRange(startDate: String!, endDate: String!): [DailyStats]
|
||||||
getTotalStats: TotalStats!
|
getTotalStats: TotalStats!
|
||||||
|
getGroupStats(groupID: String!): Groups
|
||||||
}
|
}
|
||||||
type Mutation {
|
type Mutation {
|
||||||
init: String!
|
init(mutationKey: String): String!
|
||||||
cronJob: TotalStats!
|
cronJob(mutationKey: String): TotalStats!
|
||||||
addGroup(groupID: Int, groupName: String): Groups!
|
addGroup(
|
||||||
increment(link: Boolean, command: Boolean, trigger: Boolean): DailyStats!
|
groupID: String!
|
||||||
|
groupName: String!
|
||||||
|
groupUsername: String
|
||||||
|
mutationKey: String
|
||||||
|
): Groups!
|
||||||
|
incrementGroup(
|
||||||
|
groupID: String!
|
||||||
|
linksDeleted: Int!
|
||||||
|
mutationKey: String
|
||||||
|
): Groups!
|
||||||
|
increment(
|
||||||
|
link: Boolean
|
||||||
|
command: Boolean
|
||||||
|
trigger: Boolean
|
||||||
|
mutationKey: String
|
||||||
|
): DailyStats!
|
||||||
}
|
}
|
||||||
|
|
||||||
type Groups {
|
type Groups {
|
||||||
telegramID: Int
|
telegramID: BigInt
|
||||||
name: String
|
name: String
|
||||||
|
username: String
|
||||||
|
linksDeleted: BigInt
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
updatedAt: Date
|
updatedAt: Date
|
||||||
}
|
}
|
||||||
|
|||||||
28
src/lib/lineChartArray.ts
Normal file
28
src/lib/lineChartArray.ts
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import { DailyStats } from "@/types/DailyStats";
|
||||||
|
import { LineChartArr, LineChartItem } from "@/types/LineChartStats";
|
||||||
|
|
||||||
|
const lineChartArr = (dailyStatsArr: DailyStats): LineChartArr => {
|
||||||
|
const lineChartArr = [] as LineChartArr;
|
||||||
|
|
||||||
|
if (dailyStatsArr.length) {
|
||||||
|
dailyStatsArr.forEach((item) => {
|
||||||
|
const { linksDeleted, commandResponses, timesTriggered, createdAt } =
|
||||||
|
item;
|
||||||
|
|
||||||
|
const day = new Date(Number(createdAt)).getDate();
|
||||||
|
|
||||||
|
const lineChartItem: LineChartItem = {
|
||||||
|
day,
|
||||||
|
"Links Deleted": linksDeleted,
|
||||||
|
"Command Responses": commandResponses,
|
||||||
|
"Times Triggered": timesTriggered
|
||||||
|
};
|
||||||
|
|
||||||
|
lineChartArr.push(lineChartItem);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return lineChartArr;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default lineChartArr;
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
|
|
||||||
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
|
|
||||||
/* eslint-disable */
|
|
||||||
// biome-ignore-all lint: generated file
|
|
||||||
// @ts-nocheck
|
|
||||||
/*
|
|
||||||
* This file should be your main import to use Prisma-related types and utilities in a browser.
|
|
||||||
* Use it to get access to models, enums, and input types.
|
|
||||||
*
|
|
||||||
* This file does not contain a `PrismaClient` class, nor several other helpers that are intended as server-side only.
|
|
||||||
* See `client.ts` for the standard, server-side entry point.
|
|
||||||
*
|
|
||||||
* 🟢 You can import this file directly.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import * as Prisma from './internal/prismaNamespaceBrowser'
|
|
||||||
export { Prisma }
|
|
||||||
export * as $Enums from './enums'
|
|
||||||
export * from './enums';
|
|
||||||
/**
|
|
||||||
* Model Groups
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
export type Groups = Prisma.GroupsModel
|
|
||||||
/**
|
|
||||||
* Model TotalStats
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
export type TotalStats = Prisma.TotalStatsModel
|
|
||||||
/**
|
|
||||||
* Model DailyStats
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
export type DailyStats = Prisma.DailyStatsModel
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
|
|
||||||
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
|
|
||||||
/* eslint-disable */
|
|
||||||
// biome-ignore-all lint: generated file
|
|
||||||
// @ts-nocheck
|
|
||||||
/*
|
|
||||||
* This file should be your main import to use Prisma. Through it you get access to all the models, enums, and input types.
|
|
||||||
* If you're looking for something you can import in the client-side of your application, please refer to the `browser.ts` file instead.
|
|
||||||
*
|
|
||||||
* 🟢 You can import this file directly.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import * as process from 'node:process'
|
|
||||||
import * as path from 'node:path'
|
|
||||||
import { fileURLToPath } from 'node:url'
|
|
||||||
globalThis['__dirname'] = path.dirname(fileURLToPath(import.meta.url))
|
|
||||||
|
|
||||||
import * as runtime from "@prisma/client/runtime/library"
|
|
||||||
import * as $Enums from "./enums"
|
|
||||||
import * as $Class from "./internal/class"
|
|
||||||
import * as Prisma from "./internal/prismaNamespace"
|
|
||||||
|
|
||||||
export * as $Enums from './enums'
|
|
||||||
export * from "./enums"
|
|
||||||
/**
|
|
||||||
* ## Prisma Client
|
|
||||||
*
|
|
||||||
* Type-safe database client for TypeScript
|
|
||||||
* @example
|
|
||||||
* ```
|
|
||||||
* const prisma = new PrismaClient()
|
|
||||||
* // Fetch zero or more Groups
|
|
||||||
* const groups = await prisma.groups.findMany()
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* Read more in our [docs](https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-client).
|
|
||||||
*/
|
|
||||||
export const PrismaClient = $Class.getPrismaClientClass(__dirname)
|
|
||||||
export type PrismaClient<LogOpts extends Prisma.LogLevel = never, OmitOpts extends Prisma.PrismaClientOptions["omit"] = Prisma.PrismaClientOptions["omit"], ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = $Class.PrismaClient<LogOpts, OmitOpts, ExtArgs>
|
|
||||||
export { Prisma }
|
|
||||||
|
|
||||||
|
|
||||||
// file annotations for bundling tools to include these files
|
|
||||||
path.join(__dirname, "libquery_engine-debian-openssl-3.0.x.so.node")
|
|
||||||
path.join(process.cwd(), "src/prisma/generated/libquery_engine-debian-openssl-3.0.x.so.node")
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Model Groups
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
export type Groups = Prisma.GroupsModel
|
|
||||||
/**
|
|
||||||
* Model TotalStats
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
export type TotalStats = Prisma.TotalStatsModel
|
|
||||||
/**
|
|
||||||
* Model DailyStats
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
export type DailyStats = Prisma.DailyStatsModel
|
|
||||||
@@ -1,250 +0,0 @@
|
|||||||
|
|
||||||
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
|
|
||||||
/* eslint-disable */
|
|
||||||
// biome-ignore-all lint: generated file
|
|
||||||
// @ts-nocheck
|
|
||||||
/*
|
|
||||||
* This file exports various common sort, input & filter types that are not directly linked to a particular model.
|
|
||||||
*
|
|
||||||
* 🟢 You can import this file directly.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import type * as runtime from "@prisma/client/runtime/library"
|
|
||||||
import * as $Enums from "./enums"
|
|
||||||
import type * as Prisma from "./internal/prismaNamespace"
|
|
||||||
|
|
||||||
|
|
||||||
export type IntFilter<$PrismaModel = never> = {
|
|
||||||
equals?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
|
||||||
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
|
||||||
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
|
||||||
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
|
||||||
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
|
||||||
gte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedIntFilter<$PrismaModel> | number
|
|
||||||
}
|
|
||||||
|
|
||||||
export type StringFilter<$PrismaModel = never> = {
|
|
||||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
|
||||||
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
mode?: Prisma.QueryMode
|
|
||||||
not?: Prisma.NestedStringFilter<$PrismaModel> | string
|
|
||||||
}
|
|
||||||
|
|
||||||
export type DateTimeFilter<$PrismaModel = never> = {
|
|
||||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
|
||||||
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedDateTimeFilter<$PrismaModel> | Date | string
|
|
||||||
}
|
|
||||||
|
|
||||||
export type IntWithAggregatesFilter<$PrismaModel = never> = {
|
|
||||||
equals?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
|
||||||
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
|
||||||
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
|
||||||
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
|
||||||
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
|
||||||
gte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedIntWithAggregatesFilter<$PrismaModel> | number
|
|
||||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
|
||||||
_avg?: Prisma.NestedFloatFilter<$PrismaModel>
|
|
||||||
_sum?: Prisma.NestedIntFilter<$PrismaModel>
|
|
||||||
_min?: Prisma.NestedIntFilter<$PrismaModel>
|
|
||||||
_max?: Prisma.NestedIntFilter<$PrismaModel>
|
|
||||||
}
|
|
||||||
|
|
||||||
export type StringWithAggregatesFilter<$PrismaModel = never> = {
|
|
||||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
|
||||||
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
mode?: Prisma.QueryMode
|
|
||||||
not?: Prisma.NestedStringWithAggregatesFilter<$PrismaModel> | string
|
|
||||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
|
||||||
_min?: Prisma.NestedStringFilter<$PrismaModel>
|
|
||||||
_max?: Prisma.NestedStringFilter<$PrismaModel>
|
|
||||||
}
|
|
||||||
|
|
||||||
export type DateTimeWithAggregatesFilter<$PrismaModel = never> = {
|
|
||||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
|
||||||
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedDateTimeWithAggregatesFilter<$PrismaModel> | Date | string
|
|
||||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
|
||||||
_min?: Prisma.NestedDateTimeFilter<$PrismaModel>
|
|
||||||
_max?: Prisma.NestedDateTimeFilter<$PrismaModel>
|
|
||||||
}
|
|
||||||
|
|
||||||
export type BigIntFilter<$PrismaModel = never> = {
|
|
||||||
equals?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
|
||||||
in?: bigint[] | number[] | Prisma.ListBigIntFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: bigint[] | number[] | Prisma.ListBigIntFieldRefInput<$PrismaModel>
|
|
||||||
lt?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
|
||||||
lte?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
|
||||||
gt?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
|
||||||
gte?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedBigIntFilter<$PrismaModel> | bigint | number
|
|
||||||
}
|
|
||||||
|
|
||||||
export type BigIntWithAggregatesFilter<$PrismaModel = never> = {
|
|
||||||
equals?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
|
||||||
in?: bigint[] | number[] | Prisma.ListBigIntFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: bigint[] | number[] | Prisma.ListBigIntFieldRefInput<$PrismaModel>
|
|
||||||
lt?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
|
||||||
lte?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
|
||||||
gt?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
|
||||||
gte?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedBigIntWithAggregatesFilter<$PrismaModel> | bigint | number
|
|
||||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
|
||||||
_avg?: Prisma.NestedFloatFilter<$PrismaModel>
|
|
||||||
_sum?: Prisma.NestedBigIntFilter<$PrismaModel>
|
|
||||||
_min?: Prisma.NestedBigIntFilter<$PrismaModel>
|
|
||||||
_max?: Prisma.NestedBigIntFilter<$PrismaModel>
|
|
||||||
}
|
|
||||||
|
|
||||||
export type NestedIntFilter<$PrismaModel = never> = {
|
|
||||||
equals?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
|
||||||
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
|
||||||
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
|
||||||
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
|
||||||
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
|
||||||
gte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedIntFilter<$PrismaModel> | number
|
|
||||||
}
|
|
||||||
|
|
||||||
export type NestedStringFilter<$PrismaModel = never> = {
|
|
||||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
|
||||||
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedStringFilter<$PrismaModel> | string
|
|
||||||
}
|
|
||||||
|
|
||||||
export type NestedDateTimeFilter<$PrismaModel = never> = {
|
|
||||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
|
||||||
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedDateTimeFilter<$PrismaModel> | Date | string
|
|
||||||
}
|
|
||||||
|
|
||||||
export type NestedIntWithAggregatesFilter<$PrismaModel = never> = {
|
|
||||||
equals?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
|
||||||
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
|
||||||
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
|
||||||
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
|
||||||
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
|
||||||
gte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedIntWithAggregatesFilter<$PrismaModel> | number
|
|
||||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
|
||||||
_avg?: Prisma.NestedFloatFilter<$PrismaModel>
|
|
||||||
_sum?: Prisma.NestedIntFilter<$PrismaModel>
|
|
||||||
_min?: Prisma.NestedIntFilter<$PrismaModel>
|
|
||||||
_max?: Prisma.NestedIntFilter<$PrismaModel>
|
|
||||||
}
|
|
||||||
|
|
||||||
export type NestedFloatFilter<$PrismaModel = never> = {
|
|
||||||
equals?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
|
||||||
in?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel>
|
|
||||||
lt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
|
||||||
lte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
|
||||||
gt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
|
||||||
gte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedFloatFilter<$PrismaModel> | number
|
|
||||||
}
|
|
||||||
|
|
||||||
export type NestedStringWithAggregatesFilter<$PrismaModel = never> = {
|
|
||||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
|
||||||
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedStringWithAggregatesFilter<$PrismaModel> | string
|
|
||||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
|
||||||
_min?: Prisma.NestedStringFilter<$PrismaModel>
|
|
||||||
_max?: Prisma.NestedStringFilter<$PrismaModel>
|
|
||||||
}
|
|
||||||
|
|
||||||
export type NestedDateTimeWithAggregatesFilter<$PrismaModel = never> = {
|
|
||||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
|
||||||
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedDateTimeWithAggregatesFilter<$PrismaModel> | Date | string
|
|
||||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
|
||||||
_min?: Prisma.NestedDateTimeFilter<$PrismaModel>
|
|
||||||
_max?: Prisma.NestedDateTimeFilter<$PrismaModel>
|
|
||||||
}
|
|
||||||
|
|
||||||
export type NestedBigIntFilter<$PrismaModel = never> = {
|
|
||||||
equals?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
|
||||||
in?: bigint[] | number[] | Prisma.ListBigIntFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: bigint[] | number[] | Prisma.ListBigIntFieldRefInput<$PrismaModel>
|
|
||||||
lt?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
|
||||||
lte?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
|
||||||
gt?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
|
||||||
gte?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedBigIntFilter<$PrismaModel> | bigint | number
|
|
||||||
}
|
|
||||||
|
|
||||||
export type NestedBigIntWithAggregatesFilter<$PrismaModel = never> = {
|
|
||||||
equals?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
|
||||||
in?: bigint[] | number[] | Prisma.ListBigIntFieldRefInput<$PrismaModel>
|
|
||||||
notIn?: bigint[] | number[] | Prisma.ListBigIntFieldRefInput<$PrismaModel>
|
|
||||||
lt?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
|
||||||
lte?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
|
||||||
gt?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
|
||||||
gte?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
|
||||||
not?: Prisma.NestedBigIntWithAggregatesFilter<$PrismaModel> | bigint | number
|
|
||||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
|
||||||
_avg?: Prisma.NestedFloatFilter<$PrismaModel>
|
|
||||||
_sum?: Prisma.NestedBigIntFilter<$PrismaModel>
|
|
||||||
_min?: Prisma.NestedBigIntFilter<$PrismaModel>
|
|
||||||
_max?: Prisma.NestedBigIntFilter<$PrismaModel>
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
|
|
||||||
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
|
|
||||||
/* eslint-disable */
|
|
||||||
// biome-ignore-all lint: generated file
|
|
||||||
// @ts-nocheck
|
|
||||||
/*
|
|
||||||
* This file exports all enum related types from the schema.
|
|
||||||
*
|
|
||||||
* 🟢 You can import this file directly.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// This file is empty because there are no enums in the schema.
|
|
||||||
export {}
|
|
||||||
@@ -1,206 +0,0 @@
|
|||||||
|
|
||||||
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
|
|
||||||
/* eslint-disable */
|
|
||||||
// biome-ignore-all lint: generated file
|
|
||||||
// @ts-nocheck
|
|
||||||
/*
|
|
||||||
* WARNING: This is an internal file that is subject to change!
|
|
||||||
*
|
|
||||||
* 🛑 Under no circumstances should you import this file directly! 🛑
|
|
||||||
*
|
|
||||||
* Please import the `PrismaClient` class from the `client.ts` file instead.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import * as runtime from "@prisma/client/runtime/library"
|
|
||||||
import type * as Prisma from "./prismaNamespace"
|
|
||||||
|
|
||||||
|
|
||||||
const config: runtime.GetPrismaClientConfig = {
|
|
||||||
"generator": {
|
|
||||||
"name": "client",
|
|
||||||
"provider": {
|
|
||||||
"fromEnvVar": null,
|
|
||||||
"value": "prisma-client"
|
|
||||||
},
|
|
||||||
"output": {
|
|
||||||
"value": "/home/lucid/work/cove-gitea/no-twitter-bot-stats/src/prisma/generated",
|
|
||||||
"fromEnvVar": null
|
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
"engineType": "library"
|
|
||||||
},
|
|
||||||
"binaryTargets": [
|
|
||||||
{
|
|
||||||
"fromEnvVar": null,
|
|
||||||
"value": "debian-openssl-3.0.x",
|
|
||||||
"native": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"previewFeatures": [],
|
|
||||||
"sourceFilePath": "/home/lucid/work/cove-gitea/no-twitter-bot-stats/src/prisma/schema.prisma",
|
|
||||||
"isCustomOutput": true
|
|
||||||
},
|
|
||||||
"relativePath": "..",
|
|
||||||
"clientVersion": "6.19.0",
|
|
||||||
"engineVersion": "2ba551f319ab1df4bc874a89965d8b3641056773",
|
|
||||||
"datasourceNames": [
|
|
||||||
"db"
|
|
||||||
],
|
|
||||||
"activeProvider": "mongodb",
|
|
||||||
"postinstall": true,
|
|
||||||
"inlineDatasources": {
|
|
||||||
"db": {
|
|
||||||
"url": {
|
|
||||||
"fromEnvVar": "DATABASE_URL",
|
|
||||||
"value": null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"inlineSchema": "// This is your Prisma schema file,\n// learn more about it in the docs: https://pris.ly/d/prisma-schema\n\n// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?\n// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init\n\ngenerator client {\n provider = \"prisma-client\"\n output = \"generated\"\n}\n\ndatasource db {\n provider = \"mongodb\"\n url = env(\"DATABASE_URL\")\n}\n\nmodel Groups {\n telegramID Int @id @map(\"_id\") @db.Int\n name String\n createdAt DateTime @default(now())\n updatedAt DateTime @default(now()) @updatedAt\n}\n\nmodel TotalStats {\n createdAt DateTime @id @default(now()) @map(\"_id\")\n updatedAt DateTime @default(now()) @updatedAt\n linksDeleted BigInt @default(0) @db.Long\n commandResponses BigInt @default(0) @db.Long\n timesTriggered BigInt @default(0) @db.Long\n}\n\nmodel DailyStats {\n createdAt DateTime @id @default(now()) @map(\"_id\")\n updatedAt DateTime @default(now()) @updatedAt\n linksDeleted Int @default(0) @db.Int\n commandResponses Int @default(0) @db.Int\n timesTriggered Int @default(0) @db.Int\n}\n",
|
|
||||||
"inlineSchemaHash": "0774d8717cbe04c1e3c6c3a2f861e5d37cdde6afa6ac939d315318e6dd21e64f",
|
|
||||||
"copyEngine": true,
|
|
||||||
"runtimeDataModel": {
|
|
||||||
"models": {},
|
|
||||||
"enums": {},
|
|
||||||
"types": {}
|
|
||||||
},
|
|
||||||
"dirname": ""
|
|
||||||
}
|
|
||||||
|
|
||||||
config.runtimeDataModel = JSON.parse("{\"models\":{\"Groups\":{\"dbName\":null,\"schema\":null,\"fields\":[{\"name\":\"telegramID\",\"dbName\":\"_id\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":true,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"Int\",\"nativeType\":[\"Int\",[]],\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"name\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"String\",\"nativeType\":null,\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":true,\"type\":\"DateTime\",\"nativeType\":null,\"default\":{\"name\":\"now\",\"args\":[]},\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":true,\"type\":\"DateTime\",\"nativeType\":null,\"default\":{\"name\":\"now\",\"args\":[]},\"isGenerated\":false,\"isUpdatedAt\":true}],\"primaryKey\":null,\"uniqueFields\":[],\"uniqueIndexes\":[],\"isGenerated\":false},\"TotalStats\":{\"dbName\":null,\"schema\":null,\"fields\":[{\"name\":\"createdAt\",\"dbName\":\"_id\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":true,\"isReadOnly\":false,\"hasDefaultValue\":true,\"type\":\"DateTime\",\"nativeType\":null,\"default\":{\"name\":\"now\",\"args\":[]},\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":true,\"type\":\"DateTime\",\"nativeType\":null,\"default\":{\"name\":\"now\",\"args\":[]},\"isGenerated\":false,\"isUpdatedAt\":true},{\"name\":\"linksDeleted\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":true,\"type\":\"BigInt\",\"nativeType\":[\"Long\",[]],\"default\":\"0\",\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"commandResponses\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":true,\"type\":\"BigInt\",\"nativeType\":[\"Long\",[]],\"default\":\"0\",\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"timesTriggered\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":true,\"type\":\"BigInt\",\"nativeType\":[\"Long\",[]],\"default\":\"0\",\"isGenerated\":false,\"isUpdatedAt\":false}],\"primaryKey\":null,\"uniqueFields\":[],\"uniqueIndexes\":[],\"isGenerated\":false},\"DailyStats\":{\"dbName\":null,\"schema\":null,\"fields\":[{\"name\":\"createdAt\",\"dbName\":\"_id\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":true,\"isReadOnly\":false,\"hasDefaultValue\":true,\"type\":\"DateTime\",\"nativeType\":null,\"default\":{\"name\":\"now\",\"args\":[]},\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":true,\"type\":\"DateTime\",\"nativeType\":null,\"default\":{\"name\":\"now\",\"args\":[]},\"isGenerated\":false,\"isUpdatedAt\":true},{\"name\":\"linksDeleted\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":true,\"type\":\"Int\",\"nativeType\":[\"Int\",[]],\"default\":0,\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"commandResponses\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":true,\"type\":\"Int\",\"nativeType\":[\"Int\",[]],\"default\":0,\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"timesTriggered\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":true,\"type\":\"Int\",\"nativeType\":[\"Int\",[]],\"default\":0,\"isGenerated\":false,\"isUpdatedAt\":false}],\"primaryKey\":null,\"uniqueFields\":[],\"uniqueIndexes\":[],\"isGenerated\":false}},\"enums\":{},\"types\":{}}")
|
|
||||||
config.engineWasm = undefined
|
|
||||||
config.compilerWasm = undefined
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export type LogOptions<ClientOptions extends Prisma.PrismaClientOptions> =
|
|
||||||
'log' extends keyof ClientOptions ? ClientOptions['log'] extends Array<Prisma.LogLevel | Prisma.LogDefinition> ? Prisma.GetEvents<ClientOptions['log']> : never : never
|
|
||||||
|
|
||||||
export interface PrismaClientConstructor {
|
|
||||||
/**
|
|
||||||
* ## Prisma Client
|
|
||||||
*
|
|
||||||
* Type-safe database client for TypeScript
|
|
||||||
* @example
|
|
||||||
* ```
|
|
||||||
* const prisma = new PrismaClient()
|
|
||||||
* // Fetch zero or more Groups
|
|
||||||
* const groups = await prisma.groups.findMany()
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* Read more in our [docs](https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-client).
|
|
||||||
*/
|
|
||||||
|
|
||||||
new <
|
|
||||||
Options extends Prisma.PrismaClientOptions = Prisma.PrismaClientOptions,
|
|
||||||
LogOpts extends LogOptions<Options> = LogOptions<Options>,
|
|
||||||
OmitOpts extends Prisma.PrismaClientOptions['omit'] = Options extends { omit: infer U } ? U : Prisma.PrismaClientOptions['omit'],
|
|
||||||
ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs
|
|
||||||
>(options?: Prisma.Subset<Options, Prisma.PrismaClientOptions> ): PrismaClient<LogOpts, OmitOpts, ExtArgs>
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ## Prisma Client
|
|
||||||
*
|
|
||||||
* Type-safe database client for TypeScript
|
|
||||||
* @example
|
|
||||||
* ```
|
|
||||||
* const prisma = new PrismaClient()
|
|
||||||
* // Fetch zero or more Groups
|
|
||||||
* const groups = await prisma.groups.findMany()
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* Read more in our [docs](https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-client).
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface PrismaClient<
|
|
||||||
in LogOpts extends Prisma.LogLevel = never,
|
|
||||||
in out OmitOpts extends Prisma.PrismaClientOptions['omit'] = Prisma.PrismaClientOptions['omit'],
|
|
||||||
in out ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs
|
|
||||||
> {
|
|
||||||
[K: symbol]: { types: Prisma.TypeMap<ExtArgs>['other'] }
|
|
||||||
|
|
||||||
$on<V extends LogOpts>(eventType: V, callback: (event: V extends 'query' ? Prisma.QueryEvent : Prisma.LogEvent) => void): PrismaClient;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Connect with the database
|
|
||||||
*/
|
|
||||||
$connect(): runtime.Types.Utils.JsPromise<void>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Disconnect from the database
|
|
||||||
*/
|
|
||||||
$disconnect(): runtime.Types.Utils.JsPromise<void>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allows the running of a sequence of read/write operations that are guaranteed to either succeed or fail as a whole.
|
|
||||||
* @example
|
|
||||||
* ```
|
|
||||||
* const [george, bob, alice] = await prisma.$transaction([
|
|
||||||
* prisma.user.create({ data: { name: 'George' } }),
|
|
||||||
* prisma.user.create({ data: { name: 'Bob' } }),
|
|
||||||
* prisma.user.create({ data: { name: 'Alice' } }),
|
|
||||||
* ])
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* Read more in our [docs](https://www.prisma.io/docs/concepts/components/prisma-client/transactions).
|
|
||||||
*/
|
|
||||||
$transaction<P extends Prisma.PrismaPromise<any>[]>(arg: [...P]): runtime.Types.Utils.JsPromise<runtime.Types.Utils.UnwrapTuple<P>>
|
|
||||||
|
|
||||||
$transaction<R>(fn: (prisma: Omit<PrismaClient, runtime.ITXClientDenyList>) => runtime.Types.Utils.JsPromise<R>, options?: { maxWait?: number, timeout?: number }): runtime.Types.Utils.JsPromise<R>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes a raw MongoDB command and returns the result of it.
|
|
||||||
* @example
|
|
||||||
* ```
|
|
||||||
* const user = await prisma.$runCommandRaw({
|
|
||||||
* aggregate: 'User',
|
|
||||||
* pipeline: [{ $match: { name: 'Bob' } }, { $project: { email: true, _id: false } }],
|
|
||||||
* explain: false,
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* Read more in our [docs](https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-client/raw-database-access).
|
|
||||||
*/
|
|
||||||
$runCommandRaw(command: Prisma.InputJsonObject): Prisma.PrismaPromise<Prisma.JsonObject>
|
|
||||||
|
|
||||||
$extends: runtime.Types.Extensions.ExtendsHook<"extends", Prisma.TypeMapCb<OmitOpts>, ExtArgs, runtime.Types.Utils.Call<Prisma.TypeMapCb<OmitOpts>, {
|
|
||||||
extArgs: ExtArgs
|
|
||||||
}>>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* `prisma.groups`: Exposes CRUD operations for the **Groups** model.
|
|
||||||
* Example usage:
|
|
||||||
* ```ts
|
|
||||||
* // Fetch zero or more Groups
|
|
||||||
* const groups = await prisma.groups.findMany()
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
get groups(): Prisma.GroupsDelegate<ExtArgs, { omit: OmitOpts }>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* `prisma.totalStats`: Exposes CRUD operations for the **TotalStats** model.
|
|
||||||
* Example usage:
|
|
||||||
* ```ts
|
|
||||||
* // Fetch zero or more TotalStats
|
|
||||||
* const totalStats = await prisma.totalStats.findMany()
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
get totalStats(): Prisma.TotalStatsDelegate<ExtArgs, { omit: OmitOpts }>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* `prisma.dailyStats`: Exposes CRUD operations for the **DailyStats** model.
|
|
||||||
* Example usage:
|
|
||||||
* ```ts
|
|
||||||
* // Fetch zero or more DailyStats
|
|
||||||
* const dailyStats = await prisma.dailyStats.findMany()
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
get dailyStats(): Prisma.DailyStatsDelegate<ExtArgs, { omit: OmitOpts }>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getPrismaClientClass(dirname: string): PrismaClientConstructor {
|
|
||||||
config.dirname = dirname
|
|
||||||
return runtime.getPrismaClient(config) as unknown as PrismaClientConstructor
|
|
||||||
}
|
|
||||||
@@ -1,928 +0,0 @@
|
|||||||
|
|
||||||
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
|
|
||||||
/* eslint-disable */
|
|
||||||
// biome-ignore-all lint: generated file
|
|
||||||
// @ts-nocheck
|
|
||||||
/*
|
|
||||||
* WARNING: This is an internal file that is subject to change!
|
|
||||||
*
|
|
||||||
* 🛑 Under no circumstances should you import this file directly! 🛑
|
|
||||||
*
|
|
||||||
* All exports from this file are wrapped under a `Prisma` namespace object in the client.ts file.
|
|
||||||
* While this enables partial backward compatibility, it is not part of the stable public API.
|
|
||||||
*
|
|
||||||
* If you are looking for your Models, Enums, and Input Types, please import them from the respective
|
|
||||||
* model files in the `model` directory!
|
|
||||||
*/
|
|
||||||
|
|
||||||
import * as runtime from "@prisma/client/runtime/library"
|
|
||||||
import type * as Prisma from "../models"
|
|
||||||
import { type PrismaClient } from "./class"
|
|
||||||
|
|
||||||
export type * from '../models'
|
|
||||||
|
|
||||||
export type DMMF = typeof runtime.DMMF
|
|
||||||
|
|
||||||
export type PrismaPromise<T> = runtime.Types.Public.PrismaPromise<T>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prisma Errors
|
|
||||||
*/
|
|
||||||
|
|
||||||
export const PrismaClientKnownRequestError = runtime.PrismaClientKnownRequestError
|
|
||||||
export type PrismaClientKnownRequestError = runtime.PrismaClientKnownRequestError
|
|
||||||
|
|
||||||
export const PrismaClientUnknownRequestError = runtime.PrismaClientUnknownRequestError
|
|
||||||
export type PrismaClientUnknownRequestError = runtime.PrismaClientUnknownRequestError
|
|
||||||
|
|
||||||
export const PrismaClientRustPanicError = runtime.PrismaClientRustPanicError
|
|
||||||
export type PrismaClientRustPanicError = runtime.PrismaClientRustPanicError
|
|
||||||
|
|
||||||
export const PrismaClientInitializationError = runtime.PrismaClientInitializationError
|
|
||||||
export type PrismaClientInitializationError = runtime.PrismaClientInitializationError
|
|
||||||
|
|
||||||
export const PrismaClientValidationError = runtime.PrismaClientValidationError
|
|
||||||
export type PrismaClientValidationError = runtime.PrismaClientValidationError
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Re-export of sql-template-tag
|
|
||||||
*/
|
|
||||||
export const sql = runtime.sqltag
|
|
||||||
export const empty = runtime.empty
|
|
||||||
export const join = runtime.join
|
|
||||||
export const raw = runtime.raw
|
|
||||||
export const Sql = runtime.Sql
|
|
||||||
export type Sql = runtime.Sql
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decimal.js
|
|
||||||
*/
|
|
||||||
export const Decimal = runtime.Decimal
|
|
||||||
export type Decimal = runtime.Decimal
|
|
||||||
|
|
||||||
export type DecimalJsLike = runtime.DecimalJsLike
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Metrics
|
|
||||||
*/
|
|
||||||
export type Metrics = runtime.Metrics
|
|
||||||
export type Metric<T> = runtime.Metric<T>
|
|
||||||
export type MetricHistogram = runtime.MetricHistogram
|
|
||||||
export type MetricHistogramBucket = runtime.MetricHistogramBucket
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extensions
|
|
||||||
*/
|
|
||||||
export type Extension = runtime.Types.Extensions.UserArgs
|
|
||||||
export const getExtensionContext = runtime.Extensions.getExtensionContext
|
|
||||||
export type Args<T, F extends runtime.Operation> = runtime.Types.Public.Args<T, F>
|
|
||||||
export type Payload<T, F extends runtime.Operation = never> = runtime.Types.Public.Payload<T, F>
|
|
||||||
export type Result<T, A, F extends runtime.Operation> = runtime.Types.Public.Result<T, A, F>
|
|
||||||
export type Exact<A, W> = runtime.Types.Public.Exact<A, W>
|
|
||||||
|
|
||||||
export type PrismaVersion = {
|
|
||||||
client: string
|
|
||||||
engine: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prisma Client JS version: 6.19.0
|
|
||||||
* Query Engine version: 2ba551f319ab1df4bc874a89965d8b3641056773
|
|
||||||
*/
|
|
||||||
export const prismaVersion: PrismaVersion = {
|
|
||||||
client: "6.19.0",
|
|
||||||
engine: "2ba551f319ab1df4bc874a89965d8b3641056773"
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility Types
|
|
||||||
*/
|
|
||||||
|
|
||||||
export type Bytes = runtime.Bytes
|
|
||||||
export type JsonObject = runtime.JsonObject
|
|
||||||
export type JsonArray = runtime.JsonArray
|
|
||||||
export type JsonValue = runtime.JsonValue
|
|
||||||
export type InputJsonObject = runtime.InputJsonObject
|
|
||||||
export type InputJsonArray = runtime.InputJsonArray
|
|
||||||
export type InputJsonValue = runtime.InputJsonValue
|
|
||||||
|
|
||||||
|
|
||||||
export const NullTypes = {
|
|
||||||
DbNull: runtime.objectEnumValues.classes.DbNull as (new (secret: never) => typeof runtime.objectEnumValues.instances.DbNull),
|
|
||||||
JsonNull: runtime.objectEnumValues.classes.JsonNull as (new (secret: never) => typeof runtime.objectEnumValues.instances.JsonNull),
|
|
||||||
AnyNull: runtime.objectEnumValues.classes.AnyNull as (new (secret: never) => typeof runtime.objectEnumValues.instances.AnyNull),
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Helper for filtering JSON entries that have `null` on the database (empty on the db)
|
|
||||||
*
|
|
||||||
* @see https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-on-a-json-field
|
|
||||||
*/
|
|
||||||
export const DbNull = runtime.objectEnumValues.instances.DbNull
|
|
||||||
/**
|
|
||||||
* Helper for filtering JSON entries that have JSON `null` values (not empty on the db)
|
|
||||||
*
|
|
||||||
* @see https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-on-a-json-field
|
|
||||||
*/
|
|
||||||
export const JsonNull = runtime.objectEnumValues.instances.JsonNull
|
|
||||||
/**
|
|
||||||
* Helper for filtering JSON entries that are `Prisma.DbNull` or `Prisma.JsonNull`
|
|
||||||
*
|
|
||||||
* @see https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-on-a-json-field
|
|
||||||
*/
|
|
||||||
export const AnyNull = runtime.objectEnumValues.instances.AnyNull
|
|
||||||
|
|
||||||
|
|
||||||
type SelectAndInclude = {
|
|
||||||
select: any
|
|
||||||
include: any
|
|
||||||
}
|
|
||||||
|
|
||||||
type SelectAndOmit = {
|
|
||||||
select: any
|
|
||||||
omit: any
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* From T, pick a set of properties whose keys are in the union K
|
|
||||||
*/
|
|
||||||
type Prisma__Pick<T, K extends keyof T> = {
|
|
||||||
[P in K]: T[P];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Enumerable<T> = T | Array<T>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Subset
|
|
||||||
* @desc From `T` pick properties that exist in `U`. Simple version of Intersection
|
|
||||||
*/
|
|
||||||
export type Subset<T, U> = {
|
|
||||||
[key in keyof T]: key extends keyof U ? T[key] : never;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SelectSubset
|
|
||||||
* @desc From `T` pick properties that exist in `U`. Simple version of Intersection.
|
|
||||||
* Additionally, it validates, if both select and include are present. If the case, it errors.
|
|
||||||
*/
|
|
||||||
export type SelectSubset<T, U> = {
|
|
||||||
[key in keyof T]: key extends keyof U ? T[key] : never
|
|
||||||
} &
|
|
||||||
(T extends SelectAndInclude
|
|
||||||
? 'Please either choose `select` or `include`.'
|
|
||||||
: T extends SelectAndOmit
|
|
||||||
? 'Please either choose `select` or `omit`.'
|
|
||||||
: {})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Subset + Intersection
|
|
||||||
* @desc From `T` pick properties that exist in `U` and intersect `K`
|
|
||||||
*/
|
|
||||||
export type SubsetIntersection<T, U, K> = {
|
|
||||||
[key in keyof T]: key extends keyof U ? T[key] : never
|
|
||||||
} &
|
|
||||||
K
|
|
||||||
|
|
||||||
type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never };
|
|
||||||
|
|
||||||
/**
|
|
||||||
* XOR is needed to have a real mutually exclusive union type
|
|
||||||
* https://stackoverflow.com/questions/42123407/does-typescript-support-mutually-exclusive-types
|
|
||||||
*/
|
|
||||||
export type XOR<T, U> =
|
|
||||||
T extends object ?
|
|
||||||
U extends object ?
|
|
||||||
(Without<T, U> & U) | (Without<U, T> & T)
|
|
||||||
: U : T
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Is T a Record?
|
|
||||||
*/
|
|
||||||
type IsObject<T extends any> = T extends Array<any>
|
|
||||||
? False
|
|
||||||
: T extends Date
|
|
||||||
? False
|
|
||||||
: T extends Uint8Array
|
|
||||||
? False
|
|
||||||
: T extends BigInt
|
|
||||||
? False
|
|
||||||
: T extends object
|
|
||||||
? True
|
|
||||||
: False
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If it's T[], return T
|
|
||||||
*/
|
|
||||||
export type UnEnumerate<T extends unknown> = T extends Array<infer U> ? U : T
|
|
||||||
|
|
||||||
/**
|
|
||||||
* From ts-toolbelt
|
|
||||||
*/
|
|
||||||
|
|
||||||
type __Either<O extends object, K extends Key> = Omit<O, K> &
|
|
||||||
{
|
|
||||||
// Merge all but K
|
|
||||||
[P in K]: Prisma__Pick<O, P & keyof O> // With K possibilities
|
|
||||||
}[K]
|
|
||||||
|
|
||||||
type EitherStrict<O extends object, K extends Key> = Strict<__Either<O, K>>
|
|
||||||
|
|
||||||
type EitherLoose<O extends object, K extends Key> = ComputeRaw<__Either<O, K>>
|
|
||||||
|
|
||||||
type _Either<
|
|
||||||
O extends object,
|
|
||||||
K extends Key,
|
|
||||||
strict extends Boolean
|
|
||||||
> = {
|
|
||||||
1: EitherStrict<O, K>
|
|
||||||
0: EitherLoose<O, K>
|
|
||||||
}[strict]
|
|
||||||
|
|
||||||
export type Either<
|
|
||||||
O extends object,
|
|
||||||
K extends Key,
|
|
||||||
strict extends Boolean = 1
|
|
||||||
> = O extends unknown ? _Either<O, K, strict> : never
|
|
||||||
|
|
||||||
export type Union = any
|
|
||||||
|
|
||||||
export type PatchUndefined<O extends object, O1 extends object> = {
|
|
||||||
[K in keyof O]: O[K] extends undefined ? At<O1, K> : O[K]
|
|
||||||
} & {}
|
|
||||||
|
|
||||||
/** Helper Types for "Merge" **/
|
|
||||||
export type IntersectOf<U extends Union> = (
|
|
||||||
U extends unknown ? (k: U) => void : never
|
|
||||||
) extends (k: infer I) => void
|
|
||||||
? I
|
|
||||||
: never
|
|
||||||
|
|
||||||
export type Overwrite<O extends object, O1 extends object> = {
|
|
||||||
[K in keyof O]: K extends keyof O1 ? O1[K] : O[K];
|
|
||||||
} & {};
|
|
||||||
|
|
||||||
type _Merge<U extends object> = IntersectOf<Overwrite<U, {
|
|
||||||
[K in keyof U]-?: At<U, K>;
|
|
||||||
}>>;
|
|
||||||
|
|
||||||
type Key = string | number | symbol;
|
|
||||||
type AtStrict<O extends object, K extends Key> = O[K & keyof O];
|
|
||||||
type AtLoose<O extends object, K extends Key> = O extends unknown ? AtStrict<O, K> : never;
|
|
||||||
export type At<O extends object, K extends Key, strict extends Boolean = 1> = {
|
|
||||||
1: AtStrict<O, K>;
|
|
||||||
0: AtLoose<O, K>;
|
|
||||||
}[strict];
|
|
||||||
|
|
||||||
export type ComputeRaw<A extends any> = A extends Function ? A : {
|
|
||||||
[K in keyof A]: A[K];
|
|
||||||
} & {};
|
|
||||||
|
|
||||||
export type OptionalFlat<O> = {
|
|
||||||
[K in keyof O]?: O[K];
|
|
||||||
} & {};
|
|
||||||
|
|
||||||
type _Record<K extends keyof any, T> = {
|
|
||||||
[P in K]: T;
|
|
||||||
};
|
|
||||||
|
|
||||||
// cause typescript not to expand types and preserve names
|
|
||||||
type NoExpand<T> = T extends unknown ? T : never;
|
|
||||||
|
|
||||||
// this type assumes the passed object is entirely optional
|
|
||||||
export type AtLeast<O extends object, K extends string> = NoExpand<
|
|
||||||
O extends unknown
|
|
||||||
? | (K extends keyof O ? { [P in K]: O[P] } & O : O)
|
|
||||||
| {[P in keyof O as P extends K ? P : never]-?: O[P]} & O
|
|
||||||
: never>;
|
|
||||||
|
|
||||||
type _Strict<U, _U = U> = U extends unknown ? U & OptionalFlat<_Record<Exclude<Keys<_U>, keyof U>, never>> : never;
|
|
||||||
|
|
||||||
export type Strict<U extends object> = ComputeRaw<_Strict<U>>;
|
|
||||||
/** End Helper Types for "Merge" **/
|
|
||||||
|
|
||||||
export type Merge<U extends object> = ComputeRaw<_Merge<Strict<U>>>;
|
|
||||||
|
|
||||||
export type Boolean = True | False
|
|
||||||
|
|
||||||
export type True = 1
|
|
||||||
|
|
||||||
export type False = 0
|
|
||||||
|
|
||||||
export type Not<B extends Boolean> = {
|
|
||||||
0: 1
|
|
||||||
1: 0
|
|
||||||
}[B]
|
|
||||||
|
|
||||||
export type Extends<A1 extends any, A2 extends any> = [A1] extends [never]
|
|
||||||
? 0 // anything `never` is false
|
|
||||||
: A1 extends A2
|
|
||||||
? 1
|
|
||||||
: 0
|
|
||||||
|
|
||||||
export type Has<U extends Union, U1 extends Union> = Not<
|
|
||||||
Extends<Exclude<U1, U>, U1>
|
|
||||||
>
|
|
||||||
|
|
||||||
export type Or<B1 extends Boolean, B2 extends Boolean> = {
|
|
||||||
0: {
|
|
||||||
0: 0
|
|
||||||
1: 1
|
|
||||||
}
|
|
||||||
1: {
|
|
||||||
0: 1
|
|
||||||
1: 1
|
|
||||||
}
|
|
||||||
}[B1][B2]
|
|
||||||
|
|
||||||
export type Keys<U extends Union> = U extends unknown ? keyof U : never
|
|
||||||
|
|
||||||
export type GetScalarType<T, O> = O extends object ? {
|
|
||||||
[P in keyof T]: P extends keyof O
|
|
||||||
? O[P]
|
|
||||||
: never
|
|
||||||
} : never
|
|
||||||
|
|
||||||
type FieldPaths<
|
|
||||||
T,
|
|
||||||
U = Omit<T, '_avg' | '_sum' | '_count' | '_min' | '_max'>
|
|
||||||
> = IsObject<T> extends True ? U : T
|
|
||||||
|
|
||||||
export type GetHavingFields<T> = {
|
|
||||||
[K in keyof T]: Or<
|
|
||||||
Or<Extends<'OR', K>, Extends<'AND', K>>,
|
|
||||||
Extends<'NOT', K>
|
|
||||||
> extends True
|
|
||||||
? // infer is only needed to not hit TS limit
|
|
||||||
// based on the brilliant idea of Pierre-Antoine Mills
|
|
||||||
// https://github.com/microsoft/TypeScript/issues/30188#issuecomment-478938437
|
|
||||||
T[K] extends infer TK
|
|
||||||
? GetHavingFields<UnEnumerate<TK> extends object ? Merge<UnEnumerate<TK>> : never>
|
|
||||||
: never
|
|
||||||
: {} extends FieldPaths<T[K]>
|
|
||||||
? never
|
|
||||||
: K
|
|
||||||
}[keyof T]
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert tuple to union
|
|
||||||
*/
|
|
||||||
type _TupleToUnion<T> = T extends (infer E)[] ? E : never
|
|
||||||
type TupleToUnion<K extends readonly any[]> = _TupleToUnion<K>
|
|
||||||
export type MaybeTupleToUnion<T> = T extends any[] ? TupleToUnion<T> : T
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Like `Pick`, but additionally can also accept an array of keys
|
|
||||||
*/
|
|
||||||
export type PickEnumerable<T, K extends Enumerable<keyof T> | keyof T> = Prisma__Pick<T, MaybeTupleToUnion<K>>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Exclude all keys with underscores
|
|
||||||
*/
|
|
||||||
export type ExcludeUnderscoreKeys<T extends string> = T extends `_${string}` ? never : T
|
|
||||||
|
|
||||||
|
|
||||||
export type FieldRef<Model, FieldType> = runtime.FieldRef<Model, FieldType>
|
|
||||||
|
|
||||||
type FieldRefInputType<Model, FieldType> = Model extends never ? never : FieldRef<Model, FieldType>
|
|
||||||
|
|
||||||
|
|
||||||
export const ModelName = {
|
|
||||||
Groups: 'Groups',
|
|
||||||
TotalStats: 'TotalStats',
|
|
||||||
DailyStats: 'DailyStats'
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export type ModelName = (typeof ModelName)[keyof typeof ModelName]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export interface TypeMapCb<GlobalOmitOptions = {}> extends runtime.Types.Utils.Fn<{extArgs: runtime.Types.Extensions.InternalArgs }, runtime.Types.Utils.Record<string, any>> {
|
|
||||||
returns: TypeMap<this['params']['extArgs'], GlobalOmitOptions>
|
|
||||||
}
|
|
||||||
|
|
||||||
export type TypeMap<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs, GlobalOmitOptions = {}> = {
|
|
||||||
globalOmitOptions: {
|
|
||||||
omit: GlobalOmitOptions
|
|
||||||
}
|
|
||||||
meta: {
|
|
||||||
modelProps: "groups" | "totalStats" | "dailyStats"
|
|
||||||
txIsolationLevel: never
|
|
||||||
}
|
|
||||||
model: {
|
|
||||||
Groups: {
|
|
||||||
payload: Prisma.$GroupsPayload<ExtArgs>
|
|
||||||
fields: Prisma.GroupsFieldRefs
|
|
||||||
operations: {
|
|
||||||
findUnique: {
|
|
||||||
args: Prisma.GroupsFindUniqueArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$GroupsPayload> | null
|
|
||||||
}
|
|
||||||
findUniqueOrThrow: {
|
|
||||||
args: Prisma.GroupsFindUniqueOrThrowArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$GroupsPayload>
|
|
||||||
}
|
|
||||||
findFirst: {
|
|
||||||
args: Prisma.GroupsFindFirstArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$GroupsPayload> | null
|
|
||||||
}
|
|
||||||
findFirstOrThrow: {
|
|
||||||
args: Prisma.GroupsFindFirstOrThrowArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$GroupsPayload>
|
|
||||||
}
|
|
||||||
findMany: {
|
|
||||||
args: Prisma.GroupsFindManyArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$GroupsPayload>[]
|
|
||||||
}
|
|
||||||
create: {
|
|
||||||
args: Prisma.GroupsCreateArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$GroupsPayload>
|
|
||||||
}
|
|
||||||
createMany: {
|
|
||||||
args: Prisma.GroupsCreateManyArgs<ExtArgs>
|
|
||||||
result: BatchPayload
|
|
||||||
}
|
|
||||||
delete: {
|
|
||||||
args: Prisma.GroupsDeleteArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$GroupsPayload>
|
|
||||||
}
|
|
||||||
update: {
|
|
||||||
args: Prisma.GroupsUpdateArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$GroupsPayload>
|
|
||||||
}
|
|
||||||
deleteMany: {
|
|
||||||
args: Prisma.GroupsDeleteManyArgs<ExtArgs>
|
|
||||||
result: BatchPayload
|
|
||||||
}
|
|
||||||
updateMany: {
|
|
||||||
args: Prisma.GroupsUpdateManyArgs<ExtArgs>
|
|
||||||
result: BatchPayload
|
|
||||||
}
|
|
||||||
upsert: {
|
|
||||||
args: Prisma.GroupsUpsertArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$GroupsPayload>
|
|
||||||
}
|
|
||||||
aggregate: {
|
|
||||||
args: Prisma.GroupsAggregateArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.Optional<Prisma.AggregateGroups>
|
|
||||||
}
|
|
||||||
groupBy: {
|
|
||||||
args: Prisma.GroupsGroupByArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.Optional<Prisma.GroupsGroupByOutputType>[]
|
|
||||||
}
|
|
||||||
findRaw: {
|
|
||||||
args: Prisma.GroupsFindRawArgs<ExtArgs>
|
|
||||||
result: Prisma.JsonObject
|
|
||||||
}
|
|
||||||
aggregateRaw: {
|
|
||||||
args: Prisma.GroupsAggregateRawArgs<ExtArgs>
|
|
||||||
result: Prisma.JsonObject
|
|
||||||
}
|
|
||||||
count: {
|
|
||||||
args: Prisma.GroupsCountArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.Optional<Prisma.GroupsCountAggregateOutputType> | number
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TotalStats: {
|
|
||||||
payload: Prisma.$TotalStatsPayload<ExtArgs>
|
|
||||||
fields: Prisma.TotalStatsFieldRefs
|
|
||||||
operations: {
|
|
||||||
findUnique: {
|
|
||||||
args: Prisma.TotalStatsFindUniqueArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$TotalStatsPayload> | null
|
|
||||||
}
|
|
||||||
findUniqueOrThrow: {
|
|
||||||
args: Prisma.TotalStatsFindUniqueOrThrowArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$TotalStatsPayload>
|
|
||||||
}
|
|
||||||
findFirst: {
|
|
||||||
args: Prisma.TotalStatsFindFirstArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$TotalStatsPayload> | null
|
|
||||||
}
|
|
||||||
findFirstOrThrow: {
|
|
||||||
args: Prisma.TotalStatsFindFirstOrThrowArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$TotalStatsPayload>
|
|
||||||
}
|
|
||||||
findMany: {
|
|
||||||
args: Prisma.TotalStatsFindManyArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$TotalStatsPayload>[]
|
|
||||||
}
|
|
||||||
create: {
|
|
||||||
args: Prisma.TotalStatsCreateArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$TotalStatsPayload>
|
|
||||||
}
|
|
||||||
createMany: {
|
|
||||||
args: Prisma.TotalStatsCreateManyArgs<ExtArgs>
|
|
||||||
result: BatchPayload
|
|
||||||
}
|
|
||||||
delete: {
|
|
||||||
args: Prisma.TotalStatsDeleteArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$TotalStatsPayload>
|
|
||||||
}
|
|
||||||
update: {
|
|
||||||
args: Prisma.TotalStatsUpdateArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$TotalStatsPayload>
|
|
||||||
}
|
|
||||||
deleteMany: {
|
|
||||||
args: Prisma.TotalStatsDeleteManyArgs<ExtArgs>
|
|
||||||
result: BatchPayload
|
|
||||||
}
|
|
||||||
updateMany: {
|
|
||||||
args: Prisma.TotalStatsUpdateManyArgs<ExtArgs>
|
|
||||||
result: BatchPayload
|
|
||||||
}
|
|
||||||
upsert: {
|
|
||||||
args: Prisma.TotalStatsUpsertArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$TotalStatsPayload>
|
|
||||||
}
|
|
||||||
aggregate: {
|
|
||||||
args: Prisma.TotalStatsAggregateArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.Optional<Prisma.AggregateTotalStats>
|
|
||||||
}
|
|
||||||
groupBy: {
|
|
||||||
args: Prisma.TotalStatsGroupByArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.Optional<Prisma.TotalStatsGroupByOutputType>[]
|
|
||||||
}
|
|
||||||
findRaw: {
|
|
||||||
args: Prisma.TotalStatsFindRawArgs<ExtArgs>
|
|
||||||
result: Prisma.JsonObject
|
|
||||||
}
|
|
||||||
aggregateRaw: {
|
|
||||||
args: Prisma.TotalStatsAggregateRawArgs<ExtArgs>
|
|
||||||
result: Prisma.JsonObject
|
|
||||||
}
|
|
||||||
count: {
|
|
||||||
args: Prisma.TotalStatsCountArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.Optional<Prisma.TotalStatsCountAggregateOutputType> | number
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DailyStats: {
|
|
||||||
payload: Prisma.$DailyStatsPayload<ExtArgs>
|
|
||||||
fields: Prisma.DailyStatsFieldRefs
|
|
||||||
operations: {
|
|
||||||
findUnique: {
|
|
||||||
args: Prisma.DailyStatsFindUniqueArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$DailyStatsPayload> | null
|
|
||||||
}
|
|
||||||
findUniqueOrThrow: {
|
|
||||||
args: Prisma.DailyStatsFindUniqueOrThrowArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$DailyStatsPayload>
|
|
||||||
}
|
|
||||||
findFirst: {
|
|
||||||
args: Prisma.DailyStatsFindFirstArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$DailyStatsPayload> | null
|
|
||||||
}
|
|
||||||
findFirstOrThrow: {
|
|
||||||
args: Prisma.DailyStatsFindFirstOrThrowArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$DailyStatsPayload>
|
|
||||||
}
|
|
||||||
findMany: {
|
|
||||||
args: Prisma.DailyStatsFindManyArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$DailyStatsPayload>[]
|
|
||||||
}
|
|
||||||
create: {
|
|
||||||
args: Prisma.DailyStatsCreateArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$DailyStatsPayload>
|
|
||||||
}
|
|
||||||
createMany: {
|
|
||||||
args: Prisma.DailyStatsCreateManyArgs<ExtArgs>
|
|
||||||
result: BatchPayload
|
|
||||||
}
|
|
||||||
delete: {
|
|
||||||
args: Prisma.DailyStatsDeleteArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$DailyStatsPayload>
|
|
||||||
}
|
|
||||||
update: {
|
|
||||||
args: Prisma.DailyStatsUpdateArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$DailyStatsPayload>
|
|
||||||
}
|
|
||||||
deleteMany: {
|
|
||||||
args: Prisma.DailyStatsDeleteManyArgs<ExtArgs>
|
|
||||||
result: BatchPayload
|
|
||||||
}
|
|
||||||
updateMany: {
|
|
||||||
args: Prisma.DailyStatsUpdateManyArgs<ExtArgs>
|
|
||||||
result: BatchPayload
|
|
||||||
}
|
|
||||||
upsert: {
|
|
||||||
args: Prisma.DailyStatsUpsertArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$DailyStatsPayload>
|
|
||||||
}
|
|
||||||
aggregate: {
|
|
||||||
args: Prisma.DailyStatsAggregateArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.Optional<Prisma.AggregateDailyStats>
|
|
||||||
}
|
|
||||||
groupBy: {
|
|
||||||
args: Prisma.DailyStatsGroupByArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.Optional<Prisma.DailyStatsGroupByOutputType>[]
|
|
||||||
}
|
|
||||||
findRaw: {
|
|
||||||
args: Prisma.DailyStatsFindRawArgs<ExtArgs>
|
|
||||||
result: Prisma.JsonObject
|
|
||||||
}
|
|
||||||
aggregateRaw: {
|
|
||||||
args: Prisma.DailyStatsAggregateRawArgs<ExtArgs>
|
|
||||||
result: Prisma.JsonObject
|
|
||||||
}
|
|
||||||
count: {
|
|
||||||
args: Prisma.DailyStatsCountArgs<ExtArgs>
|
|
||||||
result: runtime.Types.Utils.Optional<Prisma.DailyStatsCountAggregateOutputType> | number
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} & {
|
|
||||||
other: {
|
|
||||||
payload: any
|
|
||||||
operations: {
|
|
||||||
$runCommandRaw: {
|
|
||||||
args: Prisma.InputJsonObject,
|
|
||||||
result: JsonObject
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enums
|
|
||||||
*/
|
|
||||||
|
|
||||||
export const GroupsScalarFieldEnum = {
|
|
||||||
telegramID: 'telegramID',
|
|
||||||
name: 'name',
|
|
||||||
createdAt: 'createdAt',
|
|
||||||
updatedAt: 'updatedAt'
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export type GroupsScalarFieldEnum = (typeof GroupsScalarFieldEnum)[keyof typeof GroupsScalarFieldEnum]
|
|
||||||
|
|
||||||
|
|
||||||
export const TotalStatsScalarFieldEnum = {
|
|
||||||
createdAt: 'createdAt',
|
|
||||||
updatedAt: 'updatedAt',
|
|
||||||
linksDeleted: 'linksDeleted',
|
|
||||||
commandResponses: 'commandResponses',
|
|
||||||
timesTriggered: 'timesTriggered'
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export type TotalStatsScalarFieldEnum = (typeof TotalStatsScalarFieldEnum)[keyof typeof TotalStatsScalarFieldEnum]
|
|
||||||
|
|
||||||
|
|
||||||
export const DailyStatsScalarFieldEnum = {
|
|
||||||
createdAt: 'createdAt',
|
|
||||||
updatedAt: 'updatedAt',
|
|
||||||
linksDeleted: 'linksDeleted',
|
|
||||||
commandResponses: 'commandResponses',
|
|
||||||
timesTriggered: 'timesTriggered'
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export type DailyStatsScalarFieldEnum = (typeof DailyStatsScalarFieldEnum)[keyof typeof DailyStatsScalarFieldEnum]
|
|
||||||
|
|
||||||
|
|
||||||
export const SortOrder = {
|
|
||||||
asc: 'asc',
|
|
||||||
desc: 'desc'
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export type SortOrder = (typeof SortOrder)[keyof typeof SortOrder]
|
|
||||||
|
|
||||||
|
|
||||||
export const QueryMode = {
|
|
||||||
default: 'default',
|
|
||||||
insensitive: 'insensitive'
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export type QueryMode = (typeof QueryMode)[keyof typeof QueryMode]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Field references
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reference to a field of type 'Int'
|
|
||||||
*/
|
|
||||||
export type IntFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Int'>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reference to a field of type 'Int[]'
|
|
||||||
*/
|
|
||||||
export type ListIntFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Int[]'>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reference to a field of type 'String'
|
|
||||||
*/
|
|
||||||
export type StringFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'String'>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reference to a field of type 'String[]'
|
|
||||||
*/
|
|
||||||
export type ListStringFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'String[]'>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reference to a field of type 'DateTime'
|
|
||||||
*/
|
|
||||||
export type DateTimeFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'DateTime'>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reference to a field of type 'DateTime[]'
|
|
||||||
*/
|
|
||||||
export type ListDateTimeFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'DateTime[]'>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reference to a field of type 'BigInt'
|
|
||||||
*/
|
|
||||||
export type BigIntFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'BigInt'>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reference to a field of type 'BigInt[]'
|
|
||||||
*/
|
|
||||||
export type ListBigIntFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'BigInt[]'>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reference to a field of type 'Float'
|
|
||||||
*/
|
|
||||||
export type FloatFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Float'>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reference to a field of type 'Float[]'
|
|
||||||
*/
|
|
||||||
export type ListFloatFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Float[]'>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Batch Payload for updateMany & deleteMany & createMany
|
|
||||||
*/
|
|
||||||
export type BatchPayload = {
|
|
||||||
count: number
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export type Datasource = {
|
|
||||||
url?: string
|
|
||||||
}
|
|
||||||
export type Datasources = {
|
|
||||||
db?: Datasource
|
|
||||||
}
|
|
||||||
|
|
||||||
export const defineExtension = runtime.Extensions.defineExtension as unknown as runtime.Types.Extensions.ExtendsHook<"define", TypeMapCb, runtime.Types.Extensions.DefaultArgs>
|
|
||||||
export type DefaultPrismaClient = PrismaClient
|
|
||||||
export type ErrorFormat = 'pretty' | 'colorless' | 'minimal'
|
|
||||||
export interface PrismaClientOptions {
|
|
||||||
/**
|
|
||||||
* Overwrites the datasource url from your schema.prisma file
|
|
||||||
*/
|
|
||||||
datasources?: Datasources
|
|
||||||
/**
|
|
||||||
* Overwrites the datasource url from your schema.prisma file
|
|
||||||
*/
|
|
||||||
datasourceUrl?: string
|
|
||||||
/**
|
|
||||||
* @default "colorless"
|
|
||||||
*/
|
|
||||||
errorFormat?: ErrorFormat
|
|
||||||
/**
|
|
||||||
* @example
|
|
||||||
* ```
|
|
||||||
* // Shorthand for `emit: 'stdout'`
|
|
||||||
* log: ['query', 'info', 'warn', 'error']
|
|
||||||
*
|
|
||||||
* // Emit as events only
|
|
||||||
* log: [
|
|
||||||
* { emit: 'event', level: 'query' },
|
|
||||||
* { emit: 'event', level: 'info' },
|
|
||||||
* { emit: 'event', level: 'warn' }
|
|
||||||
* { emit: 'event', level: 'error' }
|
|
||||||
* ]
|
|
||||||
*
|
|
||||||
* / Emit as events and log to stdout
|
|
||||||
* og: [
|
|
||||||
* { emit: 'stdout', level: 'query' },
|
|
||||||
* { emit: 'stdout', level: 'info' },
|
|
||||||
* { emit: 'stdout', level: 'warn' }
|
|
||||||
* { emit: 'stdout', level: 'error' }
|
|
||||||
*
|
|
||||||
* ```
|
|
||||||
* Read more in our [docs](https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-client/logging#the-log-option).
|
|
||||||
*/
|
|
||||||
log?: (LogLevel | LogDefinition)[]
|
|
||||||
/**
|
|
||||||
* The default values for transactionOptions
|
|
||||||
* maxWait ?= 2000
|
|
||||||
* timeout ?= 5000
|
|
||||||
*/
|
|
||||||
transactionOptions?: {
|
|
||||||
maxWait?: number
|
|
||||||
timeout?: number
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Instance of a Driver Adapter, e.g., like one provided by `@prisma/adapter-planetscale`
|
|
||||||
*/
|
|
||||||
adapter?: runtime.SqlDriverAdapterFactory | null
|
|
||||||
/**
|
|
||||||
* Global configuration for omitting model fields by default.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```
|
|
||||||
* const prisma = new PrismaClient({
|
|
||||||
* omit: {
|
|
||||||
* user: {
|
|
||||||
* password: true
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* })
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
omit?: GlobalOmitConfig
|
|
||||||
}
|
|
||||||
export type GlobalOmitConfig = {
|
|
||||||
groups?: Prisma.GroupsOmit
|
|
||||||
totalStats?: Prisma.TotalStatsOmit
|
|
||||||
dailyStats?: Prisma.DailyStatsOmit
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Types for Logging */
|
|
||||||
export type LogLevel = 'info' | 'query' | 'warn' | 'error'
|
|
||||||
export type LogDefinition = {
|
|
||||||
level: LogLevel
|
|
||||||
emit: 'stdout' | 'event'
|
|
||||||
}
|
|
||||||
|
|
||||||
export type CheckIsLogLevel<T> = T extends LogLevel ? T : never;
|
|
||||||
|
|
||||||
export type GetLogType<T> = CheckIsLogLevel<
|
|
||||||
T extends LogDefinition ? T['level'] : T
|
|
||||||
>;
|
|
||||||
|
|
||||||
export type GetEvents<T extends any[]> = T extends Array<LogLevel | LogDefinition>
|
|
||||||
? GetLogType<T[number]>
|
|
||||||
: never;
|
|
||||||
|
|
||||||
export type QueryEvent = {
|
|
||||||
timestamp: Date
|
|
||||||
query: string
|
|
||||||
params: string
|
|
||||||
duration: number
|
|
||||||
target: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export type LogEvent = {
|
|
||||||
timestamp: Date
|
|
||||||
message: string
|
|
||||||
target: string
|
|
||||||
}
|
|
||||||
/* End Types for Logging */
|
|
||||||
|
|
||||||
|
|
||||||
export type PrismaAction =
|
|
||||||
| 'findUnique'
|
|
||||||
| 'findUniqueOrThrow'
|
|
||||||
| 'findMany'
|
|
||||||
| 'findFirst'
|
|
||||||
| 'findFirstOrThrow'
|
|
||||||
| 'create'
|
|
||||||
| 'createMany'
|
|
||||||
| 'createManyAndReturn'
|
|
||||||
| 'update'
|
|
||||||
| 'updateMany'
|
|
||||||
| 'updateManyAndReturn'
|
|
||||||
| 'upsert'
|
|
||||||
| 'delete'
|
|
||||||
| 'deleteMany'
|
|
||||||
| 'executeRaw'
|
|
||||||
| 'queryRaw'
|
|
||||||
| 'aggregate'
|
|
||||||
| 'count'
|
|
||||||
| 'runCommandRaw'
|
|
||||||
| 'findRaw'
|
|
||||||
| 'groupBy'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* `PrismaClient` proxy available in interactive transactions.
|
|
||||||
*/
|
|
||||||
export type TransactionClient = Omit<DefaultPrismaClient, runtime.ITXClientDenyList>
|
|
||||||
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
|
|
||||||
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
|
|
||||||
/* eslint-disable */
|
|
||||||
// biome-ignore-all lint: generated file
|
|
||||||
// @ts-nocheck
|
|
||||||
/*
|
|
||||||
* WARNING: This is an internal file that is subject to change!
|
|
||||||
*
|
|
||||||
* 🛑 Under no circumstances should you import this file directly! 🛑
|
|
||||||
*
|
|
||||||
* All exports from this file are wrapped under a `Prisma` namespace object in the browser.ts file.
|
|
||||||
* While this enables partial backward compatibility, it is not part of the stable public API.
|
|
||||||
*
|
|
||||||
* If you are looking for your Models, Enums, and Input Types, please import them from the respective
|
|
||||||
* model files in the `model` directory!
|
|
||||||
*/
|
|
||||||
|
|
||||||
import * as runtime from "@prisma/client/runtime/index-browser"
|
|
||||||
|
|
||||||
export type * from '../models'
|
|
||||||
export type * from './prismaNamespace'
|
|
||||||
|
|
||||||
export const Decimal = runtime.Decimal
|
|
||||||
|
|
||||||
|
|
||||||
export const NullTypes = {
|
|
||||||
DbNull: runtime.objectEnumValues.classes.DbNull as (new (secret: never) => typeof runtime.objectEnumValues.instances.DbNull),
|
|
||||||
JsonNull: runtime.objectEnumValues.classes.JsonNull as (new (secret: never) => typeof runtime.objectEnumValues.instances.JsonNull),
|
|
||||||
AnyNull: runtime.objectEnumValues.classes.AnyNull as (new (secret: never) => typeof runtime.objectEnumValues.instances.AnyNull),
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Helper for filtering JSON entries that have `null` on the database (empty on the db)
|
|
||||||
*
|
|
||||||
* @see https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-on-a-json-field
|
|
||||||
*/
|
|
||||||
export const DbNull = runtime.objectEnumValues.instances.DbNull
|
|
||||||
/**
|
|
||||||
* Helper for filtering JSON entries that have JSON `null` values (not empty on the db)
|
|
||||||
*
|
|
||||||
* @see https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-on-a-json-field
|
|
||||||
*/
|
|
||||||
export const JsonNull = runtime.objectEnumValues.instances.JsonNull
|
|
||||||
/**
|
|
||||||
* Helper for filtering JSON entries that are `Prisma.DbNull` or `Prisma.JsonNull`
|
|
||||||
*
|
|
||||||
* @see https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-on-a-json-field
|
|
||||||
*/
|
|
||||||
export const AnyNull = runtime.objectEnumValues.instances.AnyNull
|
|
||||||
|
|
||||||
|
|
||||||
export const ModelName = {
|
|
||||||
Groups: 'Groups',
|
|
||||||
TotalStats: 'TotalStats',
|
|
||||||
DailyStats: 'DailyStats'
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export type ModelName = (typeof ModelName)[keyof typeof ModelName]
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Enums
|
|
||||||
*/
|
|
||||||
|
|
||||||
export const GroupsScalarFieldEnum = {
|
|
||||||
telegramID: 'telegramID',
|
|
||||||
name: 'name',
|
|
||||||
createdAt: 'createdAt',
|
|
||||||
updatedAt: 'updatedAt'
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export type GroupsScalarFieldEnum = (typeof GroupsScalarFieldEnum)[keyof typeof GroupsScalarFieldEnum]
|
|
||||||
|
|
||||||
|
|
||||||
export const TotalStatsScalarFieldEnum = {
|
|
||||||
createdAt: 'createdAt',
|
|
||||||
updatedAt: 'updatedAt',
|
|
||||||
linksDeleted: 'linksDeleted',
|
|
||||||
commandResponses: 'commandResponses',
|
|
||||||
timesTriggered: 'timesTriggered'
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export type TotalStatsScalarFieldEnum = (typeof TotalStatsScalarFieldEnum)[keyof typeof TotalStatsScalarFieldEnum]
|
|
||||||
|
|
||||||
|
|
||||||
export const DailyStatsScalarFieldEnum = {
|
|
||||||
createdAt: 'createdAt',
|
|
||||||
updatedAt: 'updatedAt',
|
|
||||||
linksDeleted: 'linksDeleted',
|
|
||||||
commandResponses: 'commandResponses',
|
|
||||||
timesTriggered: 'timesTriggered'
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export type DailyStatsScalarFieldEnum = (typeof DailyStatsScalarFieldEnum)[keyof typeof DailyStatsScalarFieldEnum]
|
|
||||||
|
|
||||||
|
|
||||||
export const SortOrder = {
|
|
||||||
asc: 'asc',
|
|
||||||
desc: 'desc'
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export type SortOrder = (typeof SortOrder)[keyof typeof SortOrder]
|
|
||||||
|
|
||||||
|
|
||||||
export const QueryMode = {
|
|
||||||
default: 'default',
|
|
||||||
insensitive: 'insensitive'
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export type QueryMode = (typeof QueryMode)[keyof typeof QueryMode]
|
|
||||||
|
|
||||||
Binary file not shown.
@@ -1,14 +0,0 @@
|
|||||||
|
|
||||||
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
|
|
||||||
/* eslint-disable */
|
|
||||||
// biome-ignore-all lint: generated file
|
|
||||||
// @ts-nocheck
|
|
||||||
/*
|
|
||||||
* This is a barrel export file for all models and their related types.
|
|
||||||
*
|
|
||||||
* 🟢 You can import this file directly.
|
|
||||||
*/
|
|
||||||
export type * from './models/Groups'
|
|
||||||
export type * from './models/TotalStats'
|
|
||||||
export type * from './models/DailyStats'
|
|
||||||
export type * from './commonInputTypes'
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -15,10 +15,12 @@ datasource db {
|
|||||||
}
|
}
|
||||||
|
|
||||||
model Groups {
|
model Groups {
|
||||||
telegramID Int @id @map("_id") @db.Int
|
telegramID BigInt @id @map("_id") @db.Long
|
||||||
name String
|
name String
|
||||||
createdAt DateTime @default(now())
|
username String @default("")
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
linksDeleted BigInt @default(0) @db.Long
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
}
|
}
|
||||||
|
|
||||||
model TotalStats {
|
model TotalStats {
|
||||||
|
|||||||
9
src/types/DailyStats.d.ts
vendored
Normal file
9
src/types/DailyStats.d.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
export interface DailyStat {
|
||||||
|
createdAt: String;
|
||||||
|
linksDeleted: number;
|
||||||
|
commandResponses: number;
|
||||||
|
timesTriggered: number;
|
||||||
|
updatedAt: Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type DailyStats = DailyStat[];
|
||||||
8
src/types/LineChartStats.d.ts
vendored
Normal file
8
src/types/LineChartStats.d.ts
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
export interface LineChartItem {
|
||||||
|
day: number;
|
||||||
|
"Links Deleted": number;
|
||||||
|
"Command Responses": number;
|
||||||
|
"Times Triggered": number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type LineChartArr = LineChartItem[];
|
||||||
Reference in New Issue
Block a user