Compare commits
	
		
			No commits in common. "7aeae9020d8b6b50aa5920bdeb7e5c06b6262b33" and "036f23b77787d6b75eb6b1fc4d6256b885e4a84f" have entirely different histories.
		
	
	
		
			7aeae9020d
			...
			036f23b777
		
	
		
							
								
								
									
										223
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										223
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -11,17 +11,13 @@ | |||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "@auth/prisma-adapter": "^2.7.2", |         "@auth/prisma-adapter": "^2.7.2", | ||||||
|         "@prisma/client": "^6.5.0", |         "@prisma/client": "^6.5.0", | ||||||
|         "@prisma/extension-accelerate": "^2.0.0", |  | ||||||
|         "@t3-oss/env-nextjs": "^0.12.0", |         "@t3-oss/env-nextjs": "^0.12.0", | ||||||
|         "@tailwindcss/typography": "^0.5.16", |         "@tailwindcss/typography": "^0.5.16", | ||||||
|         "@tanstack/react-query": "^5.69.0", |         "@tanstack/react-query": "^5.69.0", | ||||||
|         "@trpc/client": "^11.0.0", |         "@trpc/client": "^11.0.0", | ||||||
|         "@trpc/react-query": "^11.0.0", |         "@trpc/react-query": "^11.0.0", | ||||||
|         "@trpc/server": "^11.0.0", |         "@trpc/server": "^11.0.0", | ||||||
|         "cuid": "^3.0.0", |  | ||||||
|         "dompurify": "^3.2.5", |         "dompurify": "^3.2.5", | ||||||
|         "github-markdown-css": "^5.8.1", |  | ||||||
|         "gray-matter": "^4.0.3", |  | ||||||
|         "mermaid": "^11.6.0", |         "mermaid": "^11.6.0", | ||||||
|         "minio": "^8.0.5", |         "minio": "^8.0.5", | ||||||
|         "next": "^15.2.3", |         "next": "^15.2.3", | ||||||
| @ -31,9 +27,7 @@ | |||||||
|         "react-hot-toast": "^2.5.2", |         "react-hot-toast": "^2.5.2", | ||||||
|         "react-markdown": "^10.1.0", |         "react-markdown": "^10.1.0", | ||||||
|         "rehype-raw": "^7.0.0", |         "rehype-raw": "^7.0.0", | ||||||
|         "remark": "^15.0.1", |  | ||||||
|         "remark-gfm": "^4.0.1", |         "remark-gfm": "^4.0.1", | ||||||
|         "remark-html": "^16.0.1", |  | ||||||
|         "server-only": "^0.0.1", |         "server-only": "^0.0.1", | ||||||
|         "superjson": "^2.2.1", |         "superjson": "^2.2.1", | ||||||
|         "zod": "^3.24.2" |         "zod": "^3.24.2" | ||||||
| @ -42,7 +36,6 @@ | |||||||
|         "@eslint/eslintrc": "^3.3.1", |         "@eslint/eslintrc": "^3.3.1", | ||||||
|         "@tailwindcss/postcss": "^4.0.15", |         "@tailwindcss/postcss": "^4.0.15", | ||||||
|         "@types/busboy": "^1.5.4", |         "@types/busboy": "^1.5.4", | ||||||
|         "@types/mime-types": "^2.1.4", |  | ||||||
|         "@types/node": "^20.14.10", |         "@types/node": "^20.14.10", | ||||||
|         "@types/react": "^19.0.0", |         "@types/react": "^19.0.0", | ||||||
|         "@types/react-dom": "^19.0.0", |         "@types/react-dom": "^19.0.0", | ||||||
| @ -1548,17 +1541,6 @@ | |||||||
|       "devOptional": true, |       "devOptional": true, | ||||||
|       "license": "Apache-2.0" |       "license": "Apache-2.0" | ||||||
|     }, |     }, | ||||||
|     "node_modules/@prisma/extension-accelerate": { |  | ||||||
|       "version": "2.0.0", |  | ||||||
|       "resolved": "https://registry.npmjs.org/@prisma/extension-accelerate/-/extension-accelerate-2.0.0.tgz", |  | ||||||
|       "integrity": "sha512-8phE1FQ/sqNQM5VRnWog2jp3r+/acffIJR1D7QHPk8d/WHdKUyLhIVSKnd1Gq+5orwzzW2I0O16gvb6Uzp0PRw==", |  | ||||||
|       "engines": { |  | ||||||
|         "node": ">=18" |  | ||||||
|       }, |  | ||||||
|       "peerDependencies": { |  | ||||||
|         "@prisma/client": ">=4.16.1" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "node_modules/@prisma/fetch-engine": { |     "node_modules/@prisma/fetch-engine": { | ||||||
|       "version": "6.6.0", |       "version": "6.6.0", | ||||||
|       "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.6.0.tgz", |       "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.6.0.tgz", | ||||||
| @ -2319,13 +2301,6 @@ | |||||||
|         "@types/unist": "*" |         "@types/unist": "*" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/@types/mime-types": { |  | ||||||
|       "version": "2.1.4", |  | ||||||
|       "resolved": "https://registry.npmjs.org/@types/mime-types/-/mime-types-2.1.4.tgz", |  | ||||||
|       "integrity": "sha512-lfU4b34HOri+kAY5UheuFMWPDOI+OPceBSHZKp69gEyTL/mmJ4cnU6Y/rlme3UL3GyOn6Y42hyIEw0/q8sWx5w==", |  | ||||||
|       "dev": true, |  | ||||||
|       "license": "MIT" |  | ||||||
|     }, |  | ||||||
|     "node_modules/@types/ms": { |     "node_modules/@types/ms": { | ||||||
|       "version": "2.1.0", |       "version": "2.1.0", | ||||||
|       "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", |       "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", | ||||||
| @ -3533,13 +3508,6 @@ | |||||||
|       "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", |       "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", | ||||||
|       "license": "MIT" |       "license": "MIT" | ||||||
|     }, |     }, | ||||||
|     "node_modules/cuid": { |  | ||||||
|       "version": "3.0.0", |  | ||||||
|       "resolved": "https://registry.npmjs.org/cuid/-/cuid-3.0.0.tgz", |  | ||||||
|       "integrity": "sha512-WZYYkHdIDnaxdeP8Misq3Lah5vFjJwGuItJuV+tvMafosMzw0nF297T7mrm8IOWiPJkV6gc7sa8pzx27+w25Zg==", |  | ||||||
|       "deprecated": "Cuid and other k-sortable and non-cryptographic ids (Ulid, ObjectId, KSUID, all UUIDs) are all insecure. Use @paralleldrive/cuid2 instead.", |  | ||||||
|       "license": "MIT" |  | ||||||
|     }, |  | ||||||
|     "node_modules/cytoscape": { |     "node_modules/cytoscape": { | ||||||
|       "version": "3.32.0", |       "version": "3.32.0", | ||||||
|       "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.32.0.tgz", |       "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.32.0.tgz", | ||||||
| @ -4915,19 +4883,6 @@ | |||||||
|         "url": "https://opencollective.com/eslint" |         "url": "https://opencollective.com/eslint" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/esprima": { |  | ||||||
|       "version": "4.0.1", |  | ||||||
|       "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", |  | ||||||
|       "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", |  | ||||||
|       "license": "BSD-2-Clause", |  | ||||||
|       "bin": { |  | ||||||
|         "esparse": "bin/esparse.js", |  | ||||||
|         "esvalidate": "bin/esvalidate.js" |  | ||||||
|       }, |  | ||||||
|       "engines": { |  | ||||||
|         "node": ">=4" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "node_modules/esquery": { |     "node_modules/esquery": { | ||||||
|       "version": "1.6.0", |       "version": "1.6.0", | ||||||
|       "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", |       "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", | ||||||
| @ -5002,18 +4957,6 @@ | |||||||
|       "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", |       "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", | ||||||
|       "license": "MIT" |       "license": "MIT" | ||||||
|     }, |     }, | ||||||
|     "node_modules/extend-shallow": { |  | ||||||
|       "version": "2.0.1", |  | ||||||
|       "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", |  | ||||||
|       "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", |  | ||||||
|       "license": "MIT", |  | ||||||
|       "dependencies": { |  | ||||||
|         "is-extendable": "^0.1.0" |  | ||||||
|       }, |  | ||||||
|       "engines": { |  | ||||||
|         "node": ">=0.10.0" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "node_modules/fast-deep-equal": { |     "node_modules/fast-deep-equal": { | ||||||
|       "version": "3.1.3", |       "version": "3.1.3", | ||||||
|       "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", |       "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", | ||||||
| @ -5304,18 +5247,6 @@ | |||||||
|         "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" |         "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/github-markdown-css": { |  | ||||||
|       "version": "5.8.1", |  | ||||||
|       "resolved": "https://registry.npmjs.org/github-markdown-css/-/github-markdown-css-5.8.1.tgz", |  | ||||||
|       "integrity": "sha512-8G+PFvqigBQSWLQjyzgpa2ThD9bo7+kDsriUIidGcRhXgmcaAWUIpCZf8DavJgc+xifjbCG+GvMyWr0XMXmc7g==", |  | ||||||
|       "license": "MIT", |  | ||||||
|       "engines": { |  | ||||||
|         "node": ">=10" |  | ||||||
|       }, |  | ||||||
|       "funding": { |  | ||||||
|         "url": "https://github.com/sponsors/sindresorhus" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "node_modules/glob-parent": { |     "node_modules/glob-parent": { | ||||||
|       "version": "6.0.2", |       "version": "6.0.2", | ||||||
|       "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", |       "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", | ||||||
| @ -5394,43 +5325,6 @@ | |||||||
|       "dev": true, |       "dev": true, | ||||||
|       "license": "MIT" |       "license": "MIT" | ||||||
|     }, |     }, | ||||||
|     "node_modules/gray-matter": { |  | ||||||
|       "version": "4.0.3", |  | ||||||
|       "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", |  | ||||||
|       "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", |  | ||||||
|       "license": "MIT", |  | ||||||
|       "dependencies": { |  | ||||||
|         "js-yaml": "^3.13.1", |  | ||||||
|         "kind-of": "^6.0.2", |  | ||||||
|         "section-matter": "^1.0.0", |  | ||||||
|         "strip-bom-string": "^1.0.0" |  | ||||||
|       }, |  | ||||||
|       "engines": { |  | ||||||
|         "node": ">=6.0" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "node_modules/gray-matter/node_modules/argparse": { |  | ||||||
|       "version": "1.0.10", |  | ||||||
|       "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", |  | ||||||
|       "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", |  | ||||||
|       "license": "MIT", |  | ||||||
|       "dependencies": { |  | ||||||
|         "sprintf-js": "~1.0.2" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "node_modules/gray-matter/node_modules/js-yaml": { |  | ||||||
|       "version": "3.14.1", |  | ||||||
|       "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", |  | ||||||
|       "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", |  | ||||||
|       "license": "MIT", |  | ||||||
|       "dependencies": { |  | ||||||
|         "argparse": "^1.0.7", |  | ||||||
|         "esprima": "^4.0.0" |  | ||||||
|       }, |  | ||||||
|       "bin": { |  | ||||||
|         "js-yaml": "bin/js-yaml.js" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "node_modules/hachure-fill": { |     "node_modules/hachure-fill": { | ||||||
|       "version": "0.5.2", |       "version": "0.5.2", | ||||||
|       "resolved": "https://registry.npmjs.org/hachure-fill/-/hachure-fill-0.5.2.tgz", |       "resolved": "https://registry.npmjs.org/hachure-fill/-/hachure-fill-0.5.2.tgz", | ||||||
| @ -5585,44 +5479,6 @@ | |||||||
|         "url": "https://opencollective.com/unified" |         "url": "https://opencollective.com/unified" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/hast-util-sanitize": { |  | ||||||
|       "version": "5.0.2", |  | ||||||
|       "resolved": "https://registry.npmjs.org/hast-util-sanitize/-/hast-util-sanitize-5.0.2.tgz", |  | ||||||
|       "integrity": "sha512-3yTWghByc50aGS7JlGhk61SPenfE/p1oaFeNwkOOyrscaOkMGrcW9+Cy/QAIOBpZxP1yqDIzFMR0+Np0i0+usg==", |  | ||||||
|       "license": "MIT", |  | ||||||
|       "dependencies": { |  | ||||||
|         "@types/hast": "^3.0.0", |  | ||||||
|         "@ungap/structured-clone": "^1.0.0", |  | ||||||
|         "unist-util-position": "^5.0.0" |  | ||||||
|       }, |  | ||||||
|       "funding": { |  | ||||||
|         "type": "opencollective", |  | ||||||
|         "url": "https://opencollective.com/unified" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "node_modules/hast-util-to-html": { |  | ||||||
|       "version": "9.0.5", |  | ||||||
|       "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", |  | ||||||
|       "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", |  | ||||||
|       "license": "MIT", |  | ||||||
|       "dependencies": { |  | ||||||
|         "@types/hast": "^3.0.0", |  | ||||||
|         "@types/unist": "^3.0.0", |  | ||||||
|         "ccount": "^2.0.0", |  | ||||||
|         "comma-separated-tokens": "^2.0.0", |  | ||||||
|         "hast-util-whitespace": "^3.0.0", |  | ||||||
|         "html-void-elements": "^3.0.0", |  | ||||||
|         "mdast-util-to-hast": "^13.0.0", |  | ||||||
|         "property-information": "^7.0.0", |  | ||||||
|         "space-separated-tokens": "^2.0.0", |  | ||||||
|         "stringify-entities": "^4.0.0", |  | ||||||
|         "zwitch": "^2.0.4" |  | ||||||
|       }, |  | ||||||
|       "funding": { |  | ||||||
|         "type": "opencollective", |  | ||||||
|         "url": "https://opencollective.com/unified" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "node_modules/hast-util-to-jsx-runtime": { |     "node_modules/hast-util-to-jsx-runtime": { | ||||||
|       "version": "2.3.6", |       "version": "2.3.6", | ||||||
|       "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", |       "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", | ||||||
| @ -6024,15 +5880,6 @@ | |||||||
|         "url": "https://github.com/sponsors/wooorm" |         "url": "https://github.com/sponsors/wooorm" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/is-extendable": { |  | ||||||
|       "version": "0.1.1", |  | ||||||
|       "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", |  | ||||||
|       "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", |  | ||||||
|       "license": "MIT", |  | ||||||
|       "engines": { |  | ||||||
|         "node": ">=0.10.0" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "node_modules/is-extglob": { |     "node_modules/is-extglob": { | ||||||
|       "version": "2.1.1", |       "version": "2.1.1", | ||||||
|       "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", |       "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", | ||||||
| @ -6468,15 +6315,6 @@ | |||||||
|       "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz", |       "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz", | ||||||
|       "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==" |       "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==" | ||||||
|     }, |     }, | ||||||
|     "node_modules/kind-of": { |  | ||||||
|       "version": "6.0.3", |  | ||||||
|       "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", |  | ||||||
|       "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", |  | ||||||
|       "license": "MIT", |  | ||||||
|       "engines": { |  | ||||||
|         "node": ">=0.10.0" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "node_modules/kolorist": { |     "node_modules/kolorist": { | ||||||
|       "version": "1.8.0", |       "version": "1.8.0", | ||||||
|       "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", |       "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", | ||||||
| @ -8878,22 +8716,6 @@ | |||||||
|         "url": "https://opencollective.com/unified" |         "url": "https://opencollective.com/unified" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/remark": { |  | ||||||
|       "version": "15.0.1", |  | ||||||
|       "resolved": "https://registry.npmjs.org/remark/-/remark-15.0.1.tgz", |  | ||||||
|       "integrity": "sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A==", |  | ||||||
|       "license": "MIT", |  | ||||||
|       "dependencies": { |  | ||||||
|         "@types/mdast": "^4.0.0", |  | ||||||
|         "remark-parse": "^11.0.0", |  | ||||||
|         "remark-stringify": "^11.0.0", |  | ||||||
|         "unified": "^11.0.0" |  | ||||||
|       }, |  | ||||||
|       "funding": { |  | ||||||
|         "type": "opencollective", |  | ||||||
|         "url": "https://opencollective.com/unified" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "node_modules/remark-gfm": { |     "node_modules/remark-gfm": { | ||||||
|       "version": "4.0.1", |       "version": "4.0.1", | ||||||
|       "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", |       "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", | ||||||
| @ -8912,23 +8734,6 @@ | |||||||
|         "url": "https://opencollective.com/unified" |         "url": "https://opencollective.com/unified" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/remark-html": { |  | ||||||
|       "version": "16.0.1", |  | ||||||
|       "resolved": "https://registry.npmjs.org/remark-html/-/remark-html-16.0.1.tgz", |  | ||||||
|       "integrity": "sha512-B9JqA5i0qZe0Nsf49q3OXyGvyXuZFDzAP2iOFLEumymuYJITVpiH1IgsTEwTpdptDmZlMDMWeDmSawdaJIGCXQ==", |  | ||||||
|       "license": "MIT", |  | ||||||
|       "dependencies": { |  | ||||||
|         "@types/mdast": "^4.0.0", |  | ||||||
|         "hast-util-sanitize": "^5.0.0", |  | ||||||
|         "hast-util-to-html": "^9.0.0", |  | ||||||
|         "mdast-util-to-hast": "^13.0.0", |  | ||||||
|         "unified": "^11.0.0" |  | ||||||
|       }, |  | ||||||
|       "funding": { |  | ||||||
|         "type": "opencollective", |  | ||||||
|         "url": "https://opencollective.com/unified" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "node_modules/remark-parse": { |     "node_modules/remark-parse": { | ||||||
|       "version": "11.0.0", |       "version": "11.0.0", | ||||||
|       "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", |       "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", | ||||||
| @ -9169,19 +8974,6 @@ | |||||||
|       "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", |       "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", | ||||||
|       "license": "MIT" |       "license": "MIT" | ||||||
|     }, |     }, | ||||||
|     "node_modules/section-matter": { |  | ||||||
|       "version": "1.0.0", |  | ||||||
|       "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", |  | ||||||
|       "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", |  | ||||||
|       "license": "MIT", |  | ||||||
|       "dependencies": { |  | ||||||
|         "extend-shallow": "^2.0.1", |  | ||||||
|         "kind-of": "^6.0.0" |  | ||||||
|       }, |  | ||||||
|       "engines": { |  | ||||||
|         "node": ">=4" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "node_modules/semver": { |     "node_modules/semver": { | ||||||
|       "version": "7.7.1", |       "version": "7.7.1", | ||||||
|       "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", |       "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", | ||||||
| @ -9427,12 +9219,6 @@ | |||||||
|         "node": ">=6" |         "node": ">=6" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/sprintf-js": { |  | ||||||
|       "version": "1.0.3", |  | ||||||
|       "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", |  | ||||||
|       "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", |  | ||||||
|       "license": "BSD-3-Clause" |  | ||||||
|     }, |  | ||||||
|     "node_modules/stable-hash": { |     "node_modules/stable-hash": { | ||||||
|       "version": "0.0.5", |       "version": "0.0.5", | ||||||
|       "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz", |       "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz", | ||||||
| @ -9618,15 +9404,6 @@ | |||||||
|         "node": ">=4" |         "node": ">=4" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/strip-bom-string": { |  | ||||||
|       "version": "1.0.0", |  | ||||||
|       "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", |  | ||||||
|       "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", |  | ||||||
|       "license": "MIT", |  | ||||||
|       "engines": { |  | ||||||
|         "node": ">=0.10.0" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "node_modules/strip-json-comments": { |     "node_modules/strip-json-comments": { | ||||||
|       "version": "3.1.1", |       "version": "3.1.1", | ||||||
|       "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", |       "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", | ||||||
|  | |||||||
| @ -23,17 +23,13 @@ | |||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "@auth/prisma-adapter": "^2.7.2", |     "@auth/prisma-adapter": "^2.7.2", | ||||||
|     "@prisma/client": "^6.5.0", |     "@prisma/client": "^6.5.0", | ||||||
|     "@prisma/extension-accelerate": "^2.0.0", |  | ||||||
|     "@t3-oss/env-nextjs": "^0.12.0", |     "@t3-oss/env-nextjs": "^0.12.0", | ||||||
|     "@tailwindcss/typography": "^0.5.16", |     "@tailwindcss/typography": "^0.5.16", | ||||||
|     "@tanstack/react-query": "^5.69.0", |     "@tanstack/react-query": "^5.69.0", | ||||||
|     "@trpc/client": "^11.0.0", |     "@trpc/client": "^11.0.0", | ||||||
|     "@trpc/react-query": "^11.0.0", |     "@trpc/react-query": "^11.0.0", | ||||||
|     "@trpc/server": "^11.0.0", |     "@trpc/server": "^11.0.0", | ||||||
|     "cuid": "^3.0.0", |  | ||||||
|     "dompurify": "^3.2.5", |     "dompurify": "^3.2.5", | ||||||
|     "github-markdown-css": "^5.8.1", |  | ||||||
|     "gray-matter": "^4.0.3", |  | ||||||
|     "mermaid": "^11.6.0", |     "mermaid": "^11.6.0", | ||||||
|     "minio": "^8.0.5", |     "minio": "^8.0.5", | ||||||
|     "next": "^15.2.3", |     "next": "^15.2.3", | ||||||
| @ -43,9 +39,7 @@ | |||||||
|     "react-hot-toast": "^2.5.2", |     "react-hot-toast": "^2.5.2", | ||||||
|     "react-markdown": "^10.1.0", |     "react-markdown": "^10.1.0", | ||||||
|     "rehype-raw": "^7.0.0", |     "rehype-raw": "^7.0.0", | ||||||
|     "remark": "^15.0.1", |  | ||||||
|     "remark-gfm": "^4.0.1", |     "remark-gfm": "^4.0.1", | ||||||
|     "remark-html": "^16.0.1", |  | ||||||
|     "server-only": "^0.0.1", |     "server-only": "^0.0.1", | ||||||
|     "superjson": "^2.2.1", |     "superjson": "^2.2.1", | ||||||
|     "zod": "^3.24.2" |     "zod": "^3.24.2" | ||||||
| @ -54,7 +48,6 @@ | |||||||
|     "@eslint/eslintrc": "^3.3.1", |     "@eslint/eslintrc": "^3.3.1", | ||||||
|     "@tailwindcss/postcss": "^4.0.15", |     "@tailwindcss/postcss": "^4.0.15", | ||||||
|     "@types/busboy": "^1.5.4", |     "@types/busboy": "^1.5.4", | ||||||
|     "@types/mime-types": "^2.1.4", |  | ||||||
|     "@types/node": "^20.14.10", |     "@types/node": "^20.14.10", | ||||||
|     "@types/react": "^19.0.0", |     "@types/react": "^19.0.0", | ||||||
|     "@types/react-dom": "^19.0.0", |     "@types/react-dom": "^19.0.0", | ||||||
|  | |||||||
| @ -4,11 +4,10 @@ | |||||||
| generator client { | generator client { | ||||||
|     provider = "prisma-client-js" |     provider = "prisma-client-js" | ||||||
|     binaryTargets = ["native", "debian-openssl-3.0.x"] |     binaryTargets = ["native", "debian-openssl-3.0.x"] | ||||||
|     output   = "/app/generated/prisma-client" |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| datasource db { | datasource db { | ||||||
|     provider = "postgresql" |     provider = "mysql" | ||||||
|     // NOTE: When using mysql or sqlserver, uncomment the @db.Text annotations in model Account below |     // NOTE: When using mysql or sqlserver, uncomment the @db.Text annotations in model Account below | ||||||
|     // Further reading: |     // Further reading: | ||||||
|     // https://next-auth.js.org/adapters/prisma#create-the-prisma-schema |     // https://next-auth.js.org/adapters/prisma#create-the-prisma-schema | ||||||
| @ -24,7 +23,7 @@ model Account { | |||||||
|     type                     String |     type                     String | ||||||
|     provider                 String |     provider                 String | ||||||
|     providerAccountId        String |     providerAccountId        String | ||||||
|     refresh_token            String? //@db.Text |     refresh_token            String? @db.Text | ||||||
|     access_token             String? // @db.Text |     access_token             String? // @db.Text | ||||||
|     expires_at               Int? |     expires_at               Int? | ||||||
|     token_type               String? |     token_type               String? | ||||||
|  | |||||||
| @ -1,70 +0,0 @@ | |||||||
| import React, { Suspense } from "react"; |  | ||||||
| import { HomeButton } from "~/app/_components/HomeButton"; // Import the client component
 |  | ||||||
| import { Toaster } from "react-hot-toast"; |  | ||||||
| import { |  | ||||||
|   FileActionsContainer, |  | ||||||
| } from "~/app/_components/ActionButtons"; // Import the client component
 |  | ||||||
| 
 |  | ||||||
| const LoadingSkeleton: React.FC = () => ( |  | ||||||
|     <main className="flex min-h-screen flex-col items-center justify-center bg-gradient-to-b from-[#2e026d] to-[#15162c] text-white"> |  | ||||||
|       <div className="absolute top-4 left-4"> |  | ||||||
|          <HomeButton /> |  | ||||||
|       </div> |  | ||||||
|       <Toaster position="top-right" reverseOrder={false} /> |  | ||||||
|       <div className="container flex flex-col items-center gap-12 px-4 py-16"> |  | ||||||
|         <h1 className="text-5xl font-extrabold tracking-tight sm:text-[5rem]"> |  | ||||||
|           <span className="text-[hsl(280,100%,70%)]">File</span> Details |  | ||||||
|         </h1> |  | ||||||
|         <div className="mt-6"> |  | ||||||
|           <svg |  | ||||||
|                       className="h-6 w-6 animate-spin text-white/70" |  | ||||||
|                       xmlns="http://www.w3.org/2000/svg" |  | ||||||
|                       fill="none" |  | ||||||
|                       viewBox="0 0 24 24" |  | ||||||
|                     > |  | ||||||
|                       <circle |  | ||||||
|                         className="opacity-25" |  | ||||||
|                         cx="12" |  | ||||||
|                         cy="12" |  | ||||||
|                         r="10" |  | ||||||
|                         stroke="currentColor" |  | ||||||
|                         strokeWidth="4" |  | ||||||
|                       /> |  | ||||||
|                       <path |  | ||||||
|                         className="opacity-75" |  | ||||||
|                         fill="currentColor" |  | ||||||
|                         d="M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z" |  | ||||||
|                       /> |  | ||||||
|                     </svg> |  | ||||||
|         </div> |  | ||||||
|         <div className="w-full max-w-md rounded-lg bg-white/10 p-6 text-white shadow-md"> |  | ||||||
|           <p> |  | ||||||
|             <strong>Name:</strong> <span className="inline-block h-6 w-24 rounded bg-white/20 animate-pulse align-middle ml-2" /> |  | ||||||
|           </p> |  | ||||||
|           <p> |  | ||||||
|             <strong>Size:</strong> <span className="inline-block h-6 w-16 rounded bg-white/20 animate-pulse align-middle ml-2" /> |  | ||||||
|           </p> |  | ||||||
|           <p> |  | ||||||
|             <strong>Owner:</strong> <span className="inline-block h-6 w-20 rounded bg-white/20 animate-pulse align-middle ml-2" /> |  | ||||||
|           </p> |  | ||||||
|           <p> |  | ||||||
|             <strong>Upload Date:</strong> <span className="inline-block h-6 w-28 rounded bg-white/20 animate-pulse align-middle ml-2" /> |  | ||||||
|           </p> |  | ||||||
|           <div> |  | ||||||
|             <strong>Description:</strong> <span className="inline-block h-6 w-40 rounded bg-white/20 animate-pulse align-middle ml-2" /> |  | ||||||
|           </div> |  | ||||||
|           <div className="mt-4 flex justify-center"> |  | ||||||
|             <FileActionsContainer |  | ||||||
|               fileId={""} |  | ||||||
|               fileName={""} |  | ||||||
|               fileUrl={""} |  | ||||||
|               isOwner={false} |  | ||||||
|               isPublic={false} |  | ||||||
|             /> |  | ||||||
|           </div> |  | ||||||
|         </div> |  | ||||||
|       </div> |  | ||||||
|     </main> |  | ||||||
| ); |  | ||||||
| 
 |  | ||||||
| export default LoadingSkeleton; |  | ||||||
| @ -59,7 +59,7 @@ export function FileActionsContainer({ | |||||||
|           console.error(err); |           console.error(err); | ||||||
|         } |         } | ||||||
|         }} |         }} | ||||||
|         className="flex items-center justify-center rounded-full bg-red-500 p-2 hover:bg-red-700" |         className="flex items-center justify-center rounded-full bg-red-500 p-2 hover:bg-red-600" | ||||||
|       > |       > | ||||||
|         <img src="/icons/delete.svg" alt="Remove" className="h-6 w-6" /> |         <img src="/icons/delete.svg" alt="Remove" className="h-6 w-6" /> | ||||||
|       </button> |       </button> | ||||||
|  | |||||||
| @ -1,11 +1,13 @@ | |||||||
| "use client"; | "use client"; | ||||||
| 
 | 
 | ||||||
| import { useEffect, useState } from "react"; | import { useEffect, useState } from "react"; | ||||||
|  | import toast from "react-hot-toast"; | ||||||
| import { useRouter } from "next/navigation"; | import { useRouter } from "next/navigation"; | ||||||
| import { env } from "~/env.js"; | import { env } from "~/env.js"; | ||||||
| import { FilePreview } from "~/app/_components/FilePreview"; | import { FilePreview } from "~/app/_components/FilePreview"; | ||||||
| import { useFileActions } from "~/app/_components/FileActions"; | import { useFileActions } from "~/app/_components/FileActions"; | ||||||
| import { FileActionsContainer } from "./ActionButtons"; | import { FileActionsContainer } from "./ActionButtons"; | ||||||
|  | import { checkOwner } from "~/utils/checkOwner"; // Import the client component
 | ||||||
| 
 | 
 | ||||||
| interface FileDetails { | interface FileDetails { | ||||||
|   id: string; |   id: string; | ||||||
| @ -71,15 +73,13 @@ export default function FileGrid({ session }: FileGridProps) { | |||||||
| 
 | 
 | ||||||
|     const eventSource = new EventSource("/api/files/stream"); |     const eventSource = new EventSource("/api/files/stream"); | ||||||
|     eventSource.onmessage = (event) => { |     eventSource.onmessage = (event) => { | ||||||
|       const data: { type: string; fileId?: string } = JSON.parse(event.data); |       const data: { type: string; file?: FileDetails; fileId?: string } = JSON.parse(event.data); | ||||||
|       console.log("SSE event:", data); | 
 | ||||||
|       if (data.type === "file-added" && data.fileId) { |       if (data.type === "file-added" && data.file) { | ||||||
|         fetchFiles(); |         setFiles((prevFiles) => (data.file ? [...prevFiles, data.file] : prevFiles)); | ||||||
|       } else if (data.type === "file-updated" && data.fileId) { |         toast.success(`File "${data.file.name}" added!`); | ||||||
|         // Fetch the updated file details
 |  | ||||||
|         fetchFiles(); |  | ||||||
|       } else if (data.type === "file-removed" && data.fileId) { |       } else if (data.type === "file-removed" && data.fileId) { | ||||||
|         setFiles((prevFiles => prevFiles.filter(file => file.id !== data.fileId))); |         setFiles((prevFiles) => prevFiles.filter((file) => file.id !== data.fileId)); | ||||||
|       } |       } | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
| @ -105,7 +105,7 @@ export default function FileGrid({ session }: FileGridProps) { | |||||||
|             key={file.id} |             key={file.id} | ||||||
|             className="flex place-content-end max-w-xs flex-col gap-4 rounded-xl bg-white/10 p-4 hover:bg-white/20" |             className="flex place-content-end max-w-xs flex-col gap-4 rounded-xl bg-white/10 p-4 hover:bg-white/20" | ||||||
|           > |           > | ||||||
|             {<div className=" self-center max-w-50"><FilePreview fileId={file.id} fileType={file.extension} share={false} /></div>} |             {<div className=" self-center max-w-50"><FilePreview fileId={file.id} fileType={file.extension} /></div>} | ||||||
| 
 | 
 | ||||||
|             <button onClick={() => router.push(pageUrl + file.url)}> |             <button onClick={() => router.push(pageUrl + file.url)}> | ||||||
|               <h3 className="text-2xl font-bold">{file.name}</h3> |               <h3 className="text-2xl font-bold">{file.name}</h3> | ||||||
|  | |||||||
| @ -1,22 +1,16 @@ | |||||||
| "use client"; | "use client"; | ||||||
| 
 | 
 | ||||||
| import { useEffect, useState } from "react"; | import { useEffect, useState } from "react"; | ||||||
| import { remark } from 'remark'; | import { getFileType } from "~/utils/fileType"; // Adjust the import path as necessary
 | ||||||
| import html from 'remark-html'; |  | ||||||
| import matter from 'gray-matter'; |  | ||||||
| import "github-markdown-css/github-markdown.css"; |  | ||||||
| import "../styles/custom.css"; // Adjust the path as necessary
 |  | ||||||
| import { MarkdownRenderer } from "../../components/MarkdownRenderer"; |  | ||||||
| 
 | 
 | ||||||
| interface FilePreviewProps { | interface FilePreviewProps { | ||||||
|   fileId: string; |   fileId: string; | ||||||
|   fileType: string; // Pass the file type as a prop
 |   fileType: string; // Pass the file type as a prop
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export function FilePreview({ fileId, fileType, share }: FilePreviewProps & { share: boolean }) { | export function FilePreview({ fileId, fileType }: FilePreviewProps) { | ||||||
|   const [mediaSrc, setMediaSrc] = useState<string | null>(null); |   const [mediaSrc, setMediaSrc] = useState<string | null>(null); | ||||||
|   const [error, setError] = useState<string | null>(null); |   const [error, setError] = useState<string | null>(null); | ||||||
|   const [markdownContent, setMarkdownContent] = useState<string | null>(null); |  | ||||||
| 
 | 
 | ||||||
|   console.log("File Type:", fileType); |   console.log("File Type:", fileType); | ||||||
| 
 | 
 | ||||||
| @ -53,53 +47,20 @@ export function FilePreview({ fileId, fileType, share }: FilePreviewProps & { sh | |||||||
|     }; |     }; | ||||||
|   }, [fileId]); |   }, [fileId]); | ||||||
| 
 | 
 | ||||||
|   useEffect(() => { |  | ||||||
|     if (fileType.startsWith("markdown")) { |  | ||||||
|       const fetchMarkdown = async () => { |  | ||||||
|         try { |  | ||||||
|           const result = await renderMarkdown({ id: fileId }); |  | ||||||
|           setMarkdownContent(result.props.postData.contentHtml); |  | ||||||
|         } catch (err) { |  | ||||||
|           console.error("Failed to fetch markdown content:", err); |  | ||||||
|         } |  | ||||||
|       }; |  | ||||||
| 
 |  | ||||||
|       fetchMarkdown(); |  | ||||||
|     } |  | ||||||
|   }, [fileId, fileType]); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|   if (error) { |   if (error) { | ||||||
|     return <div className="text-red-500">{error}</div>; |     return <div className="text-red-500">{error}</div>; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   if (!mediaSrc && !markdownContent) { |   if (!mediaSrc) { | ||||||
|     return <div>Loading...</div>; |     return <div>Loading...</div>; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   if (fileType.startsWith("markdown")) { |  | ||||||
|     if (share) { |  | ||||||
|       return ( |  | ||||||
|         <div className="overflow-y-auto max-h-96 rounded-lg shadow-md"> |  | ||||||
|           {markdownContent ? ( |  | ||||||
|             <MarkdownRenderer markdownContent={markdownContent} /> |  | ||||||
|           ) : ( |  | ||||||
|             <div>Loading markdown...</div> |  | ||||||
|           )} |  | ||||||
|         </div> |  | ||||||
|       ); |  | ||||||
|     } |  | ||||||
|     return ( |  | ||||||
|       <img src="/icons/files/code.svg" alt="Code file preview" className="max-w-full max-h-96 rounded-lg invert" /> |  | ||||||
|     ); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   if (fileType.startsWith("video")) { |   if (fileType.startsWith("video")) { | ||||||
|     return ( |     return ( | ||||||
|       <video |       <video | ||||||
|         controls |         controls | ||||||
|         className="max-w-full max-h-96 rounded-lg shadow-md" |         className="max-w-full max-h-96 rounded-lg shadow-md" | ||||||
|         src={mediaSrc || ""} |         src={mediaSrc} | ||||||
|       > |       > | ||||||
|         Your browser does not support the video tag. |         Your browser does not support the video tag. | ||||||
|       </video> |       </video> | ||||||
| @ -110,14 +71,14 @@ export function FilePreview({ fileId, fileType, share }: FilePreviewProps & { sh | |||||||
|       <audio |       <audio | ||||||
|         controls |         controls | ||||||
|         className="max-w-full max-h-96 rounded-lg shadow-md" |         className="max-w-full max-h-96 rounded-lg shadow-md" | ||||||
|         src={mediaSrc || ""} |         src={mediaSrc} | ||||||
|       > |       > | ||||||
|         Your browser does not support the audio tag. |         Your browser does not support the audio tag. | ||||||
|       </audio> |       </audio> | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|   if (fileType.startsWith("image")) { |   if (fileType.startsWith("image")) { | ||||||
|     return <img src={mediaSrc || ""} alt="Media preview" className="max-w-full max-h-96 rounded-lg shadow-md" />; |     return <img src={mediaSrc} alt="Media preview" className="max-w-full max-h-96 rounded-lg shadow-md" />; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   if (fileType.startsWith("text")) { |   if (fileType.startsWith("text")) { | ||||||
| @ -130,48 +91,17 @@ export function FilePreview({ fileId, fileType, share }: FilePreviewProps & { sh | |||||||
|       <img src="/icons/files/archive.svg" alt="Archive file preview" className="max-w-full max-h-96 rounded-lg invert" /> |       <img src="/icons/files/archive.svg" alt="Archive file preview" className="max-w-full max-h-96 rounded-lg invert" /> | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|   if (fileType.startsWith("code")) { |   if (fileType.startsWith("code") || fileType.startsWith("markdown")) { | ||||||
|     return ( |     return ( | ||||||
|       <img src="/icons/files/code.svg" alt="Code file preview" className="max-w-full max-h-96 rounded-lg invert" /> |       <img src="/icons/files/code.svg" alt="Code file preview" className="max-w-full max-h-96 rounded-lg invert" /> | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|  |   // if (fileType.startsWith("markdown")) {
 | ||||||
|  |   //   return;      
 | ||||||
|  |   //   }
 | ||||||
| 
 | 
 | ||||||
|  |   // log file type
 | ||||||
|   console.log("Unsupported file type:", fileType); |   console.log("Unsupported file type:", fileType); | ||||||
| 
 | 
 | ||||||
|   return null; |   return; | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export async function rendererMarkdown(id: string) { |  | ||||||
|   const fileContents = await fetch(`/api/files/serv?id=${encodeURIComponent(id)}`) |  | ||||||
|     .then((res) => res.text()) |  | ||||||
|     .catch((err) => { |  | ||||||
|       console.error("Failed to fetch file contents:", err); |  | ||||||
|       return null; |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|   if (!fileContents) { |  | ||||||
|     throw new Error("File contents could not be fetched."); |  | ||||||
|   } |  | ||||||
|   const matterResult = matter(fileContents); |  | ||||||
| 
 |  | ||||||
|   const processedContent = await remark() |  | ||||||
|     .use(html) |  | ||||||
|     .process(matterResult.content); |  | ||||||
|   const contentHtml = processedContent.toString(); |  | ||||||
| 
 |  | ||||||
|   return { |  | ||||||
|     id, |  | ||||||
|     contentHtml, |  | ||||||
|     ...matterResult.data, |  | ||||||
|   }; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export async function renderMarkdown({ id }: { id: string }) { |  | ||||||
|   const postData = await rendererMarkdown(id); |  | ||||||
| 
 |  | ||||||
|   return { |  | ||||||
|     props: { |  | ||||||
|       postData, |  | ||||||
|     }, |  | ||||||
|   }; |  | ||||||
| } | } | ||||||
| @ -1,45 +0,0 @@ | |||||||
| import type { Metadata } from "next"; |  | ||||||
| 
 |  | ||||||
| export async function generateMetadata({ |  | ||||||
|   searchParams, |  | ||||||
| }: { |  | ||||||
|   searchParams: { id?: string }; |  | ||||||
| }): Promise<Metadata> { |  | ||||||
|   const fileId = searchParams.id; |  | ||||||
| 
 |  | ||||||
|   if (!fileId) { |  | ||||||
|     return { |  | ||||||
|       title: "File Not Found", |  | ||||||
|       description: "The file you are looking for does not exist.", |  | ||||||
|     }; |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   // Fetch file details for metadata
 |  | ||||||
|   const response = await fetch( |  | ||||||
|     `${process.env.NEXT_PUBLIC_PAGE_URL}/api/files/share?id=${encodeURIComponent(fileId)}`, |  | ||||||
|     { cache: "no-store" }, |  | ||||||
|   ); |  | ||||||
|   if (!response.ok) { |  | ||||||
|     return { |  | ||||||
|       title: "File Not Found", |  | ||||||
|       description: "The file you are looking for does not exist.", |  | ||||||
|     }; |  | ||||||
|   } |  | ||||||
|   const fileDetails = await response.json(); |  | ||||||
| 
 |  | ||||||
|   return { |  | ||||||
|     title: fileDetails.name, |  | ||||||
|     description: fileDetails.description || fileDetails.name, |  | ||||||
|     openGraph: { |  | ||||||
|       title: fileDetails.name, |  | ||||||
|       description: fileDetails.description || fileDetails.name, |  | ||||||
|       url: `${process.env.NEXT_PUBLIC_PAGE_URL}/share?id=${fileDetails.id}`, |  | ||||||
|       images: [ |  | ||||||
|         { |  | ||||||
|           url: `${process.env.NEXT_PUBLIC_PAGE_URL}/api/files/serv?id=${fileDetails.id}`, |  | ||||||
|           alt: `${fileDetails.name} preview`, |  | ||||||
|         }, |  | ||||||
|       ], |  | ||||||
|     }, |  | ||||||
|   }; |  | ||||||
| } |  | ||||||
| @ -10,7 +10,6 @@ export default function UploadForm() { | |||||||
|   const [uploadedFileUrl, setUploadedFileUrl] = useState<string | null>(null); |   const [uploadedFileUrl, setUploadedFileUrl] = useState<string | null>(null); | ||||||
|   const [progress, setProgress] = useState<number>(0); // Track upload progress
 |   const [progress, setProgress] = useState<number>(0); // Track upload progress
 | ||||||
|   const fileInputRef = useRef<HTMLInputElement | null>(null); // Ref for the file input
 |   const fileInputRef = useRef<HTMLInputElement | null>(null); // Ref for the file input
 | ||||||
|   const [isDragActive, setIsDragActive] = useState(false); // Track drag state
 |  | ||||||
| 
 | 
 | ||||||
|   const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => { |   const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => { | ||||||
|     if (e.target.files) { |     if (e.target.files) { | ||||||
| @ -21,34 +20,6 @@ export default function UploadForm() { | |||||||
|     } |     } | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   // Drag and drop handlers
 |  | ||||||
|   const handleDragOver = (e: React.DragEvent<HTMLDivElement>) => { |  | ||||||
|     e.preventDefault(); |  | ||||||
|     e.stopPropagation(); |  | ||||||
|     setIsDragActive(true); |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   const handleDragLeave = (e: React.DragEvent<HTMLDivElement>) => { |  | ||||||
|     e.preventDefault(); |  | ||||||
|     e.stopPropagation(); |  | ||||||
|     setIsDragActive(false); |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   const handleDrop = (e: React.DragEvent<HTMLDivElement>) => { |  | ||||||
|     e.preventDefault(); |  | ||||||
|     e.stopPropagation(); |  | ||||||
|     setIsDragActive(false); |  | ||||||
|     if (e.dataTransfer.files && e.dataTransfer.files.length > 0) { |  | ||||||
|       setFile(e.dataTransfer.files[0] ?? null); |  | ||||||
|       setUploadedFileUrl(null); |  | ||||||
|       setProgress(0); |  | ||||||
|       setUploading(false); |  | ||||||
|       if (fileInputRef.current) { |  | ||||||
|         fileInputRef.current.value = ""; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   const handleUpload = async () => { |   const handleUpload = async () => { | ||||||
|     if (!file) return toast.error("Please select a file to upload."); |     if (!file) return toast.error("Please select a file to upload."); | ||||||
|     setUploading(true); |     setUploading(true); | ||||||
| @ -70,14 +41,15 @@ export default function UploadForm() { | |||||||
| 
 | 
 | ||||||
|       xhr.onload = () => { |       xhr.onload = () => { | ||||||
|         if (xhr.status === 200) { |         if (xhr.status === 200) { | ||||||
|           const response = JSON.parse(xhr.responseText); |           const response: { url: string } = JSON.parse(xhr.responseText); // Explicitly type the response
 | ||||||
|           setUploadedFileUrl(response.file?.url || null); // Use the new response structure
 |           setUploadedFileUrl(response.url); // Assume the API returns the uploaded file URL
 | ||||||
|  |           notifyClients({type: "file-uploaded", fileUrl: response.url}); // Notify other clients about the new file
 | ||||||
|           toast.success("File uploaded successfully!"); |           toast.success("File uploaded successfully!"); | ||||||
| 
 | 
 | ||||||
|           // Clear the file input and reset state
 |           // Clear the file input and reset state
 | ||||||
|           setFile(null); |           setFile(null); | ||||||
|           if (fileInputRef.current) { |           if (fileInputRef.current) { | ||||||
|             fileInputRef.current.value = ""; |             fileInputRef.current.value = ""; // Clear the file input
 | ||||||
|           } |           } | ||||||
|         } else { |         } else { | ||||||
|           console.error("Upload failed:", xhr.responseText); |           console.error("Upload failed:", xhr.responseText); | ||||||
| @ -114,48 +86,42 @@ export default function UploadForm() { | |||||||
|       {/* Toast container */} |       {/* Toast container */} | ||||||
|       <Toaster position="top-right" reverseOrder={false} /> |       <Toaster position="top-right" reverseOrder={false} /> | ||||||
| 
 | 
 | ||||||
|       {/* Drag and Drop Area */} |  | ||||||
|       <div |  | ||||||
|         className={`w-full max-w-md flex flex-col items-center justify-center border-2 border-dashed rounded-lg p-6 mb-2 transition-colors duration-200 ${isDragActive ? "border-blue-500 bg-blue-100/30" : "border-gray-400 bg-transparent hover:bg-gray-50/10"}`} |  | ||||||
|         onDragOver={handleDragOver} |  | ||||||
|         onDragLeave={handleDragLeave} |  | ||||||
|         onDrop={handleDrop} |  | ||||||
|         onClick={() => fileInputRef.current?.click()} |  | ||||||
|         style={{ cursor: "pointer" }} |  | ||||||
|       > |  | ||||||
|         {/* Hidden file input for click-to-select */} |  | ||||||
|         <input |  | ||||||
|           type="file" |  | ||||||
|           ref={fileInputRef} |  | ||||||
|           style={{ display: "none" }} |  | ||||||
|           onChange={handleFileChange} |  | ||||||
|         /> |  | ||||||
|         <span className="text-gray-300"> |  | ||||||
|           {isDragActive ? "Drop your file here" : "Drag & drop a file here, or click to select"} |  | ||||||
|         </span> |  | ||||||
|         {file && ( |  | ||||||
|           <div className="mt-2 flex items-center gap-2"> |  | ||||||
|         <span className="text-green-500 font-semibold">{file.name}</span> |  | ||||||
|         {/* Add button to remove file */} |  | ||||||
|         <button |  | ||||||
|           onClick={e => { |  | ||||||
|             e.stopPropagation(); |  | ||||||
|             setFile(null); |  | ||||||
|             if (fileInputRef.current) { |  | ||||||
|           fileInputRef.current.value = ""; |  | ||||||
|             } |  | ||||||
|           }} |  | ||||||
|           className="flex items-center justify-center rounded-full bg-red-500 p-2 hover:bg-red-700" |  | ||||||
|           style={{ cursor: "pointer" }} |  | ||||||
|         > |  | ||||||
|           <img src="/icons/delete.svg" alt="Remove" className="h-6 w-6" /> |  | ||||||
|         </button> |  | ||||||
|           </div> |  | ||||||
|         )} |  | ||||||
|       </div> |  | ||||||
|       {/* Show upload button only when file is selected */} |  | ||||||
|       {file && ( |  | ||||||
|       <div className="flex flex-row items-center gap-4"> |       <div className="flex flex-row items-center gap-4"> | ||||||
|  |         {/* Custom file input */} | ||||||
|  |         <label | ||||||
|  |           htmlFor="file-upload" | ||||||
|  |           className="cursor-pointer flex items-center gap-2 rounded-full bg-white/10 px-10 py-3 font-semibold no-underline transition hover:bg-white/20" | ||||||
|  |         > | ||||||
|  |           {file ? ( | ||||||
|  |             <> | ||||||
|  |               File Selected | ||||||
|  |               {/* SVG Icon */} | ||||||
|  |               <svg | ||||||
|  |                 xmlns="http://www.w3.org/2000/svg" | ||||||
|  |                 fill="none" | ||||||
|  |                 viewBox="0 0 24 24" | ||||||
|  |                 strokeWidth={2} | ||||||
|  |                 stroke="currentColor" | ||||||
|  |                 className="h-5 w-5 text-green-500" | ||||||
|  |               > | ||||||
|  |                 <path | ||||||
|  |                   strokeLinecap="round" | ||||||
|  |                   strokeLinejoin="round" | ||||||
|  |                   d="M5 13l4 4L19 7" | ||||||
|  |                 /> | ||||||
|  |               </svg> | ||||||
|  |             </> | ||||||
|  |           ) : ( | ||||||
|  |             "Select File" | ||||||
|  |           )} | ||||||
|  |         </label> | ||||||
|  |         <input | ||||||
|  |           id="file-upload" | ||||||
|  |           ref={fileInputRef} // Attach the ref to the file input
 | ||||||
|  |           type="file" | ||||||
|  |           onChange={handleFileChange} | ||||||
|  |           className="hidden" // Hide the default file input
 | ||||||
|  |         /> | ||||||
|         <button |         <button | ||||||
|           onClick={handleUpload} |           onClick={handleUpload} | ||||||
|           disabled={uploading || !file} |           disabled={uploading || !file} | ||||||
| @ -163,7 +129,7 @@ export default function UploadForm() { | |||||||
|         > |         > | ||||||
|           {uploading ? "Uploading..." : "Upload"} |           {uploading ? "Uploading..." : "Upload"} | ||||||
|         </button> |         </button> | ||||||
|       </div>)} |       </div> | ||||||
| 
 | 
 | ||||||
|       {file && uploading && ( |       {file && uploading && ( | ||||||
|         <div className="w-full max-w-md flex items-center gap-2"> |         <div className="w-full max-w-md flex items-center gap-2"> | ||||||
| @ -176,17 +142,31 @@ export default function UploadForm() { | |||||||
|         </div> |         </div> | ||||||
|       )} |       )} | ||||||
| 
 | 
 | ||||||
|       {/* {uploadedFileUrl && file && ( |       {uploadedFileUrl && ( | ||||||
|         <div className="flex flex-row items-center gap-4"> |         <div className="flex flex-row items-center gap-4"> | ||||||
|           <p className="text-white">{file.name}</p> |           <p className="text-white">{uploadedFileUrl}</p> | ||||||
|           <button |           <button | ||||||
|             onClick={handleCopyUrl} |             onClick={handleCopyUrl} | ||||||
|             className="flex items-center justify-center rounded-full bg-blue-500 p-2 hover:bg-blue-600" |             className="flex items-center justify-center rounded-full bg-blue-500 p-2 hover:bg-blue-600" | ||||||
|           > |           > | ||||||
|             <img src="/icons/copy.svg" alt="Copy URL" className="h-6 w-6" /> |             {/* Copy Icon */} | ||||||
|  |             <svg | ||||||
|  |               xmlns="http://www.w3.org/2000/svg" | ||||||
|  |               fill="none" | ||||||
|  |               viewBox="0 0 24 24" | ||||||
|  |               strokeWidth={2} | ||||||
|  |               stroke="currentColor" | ||||||
|  |               className="h-5 w-5 text-white" | ||||||
|  |             > | ||||||
|  |               <path | ||||||
|  |                 strokeLinecap="round" | ||||||
|  |                 strokeLinejoin="round" | ||||||
|  |                 d="M8 16h8M8 12h8m-7 8h6a2 2 0 002-2V6a2 2 0 00-2-2H9a2 2 0 00-2 2v12a2 2 0 002 2z" | ||||||
|  |               /> | ||||||
|  |             </svg> | ||||||
|           </button> |           </button> | ||||||
|         </div> |         </div> | ||||||
|       )} */} |       )} | ||||||
|     </div> |     </div> | ||||||
|   ); |   ); | ||||||
| } | } | ||||||
| @ -1,12 +1,10 @@ | |||||||
| import { NextResponse } from "next/server"; | import { NextResponse } from "next/server"; | ||||||
| import Busboy from "busboy"; | import Busboy from "busboy"; | ||||||
| import { Readable } from "stream"; | import { Readable } from "stream"; | ||||||
|  | import crypto from "crypto"; | ||||||
| import { db } from "~/server/db"; | import { db } from "~/server/db"; | ||||||
| import { auth } from "~/server/auth"; | import { auth } from "~/server/auth"; | ||||||
| import { minioClient, ensureBucketExists } from "~/utils/minioClient"; | import { minioClient, ensureBucketExists } from "~/utils/minioClient"; | ||||||
| import { getFileType } from "~/utils/fileType"; |  | ||||||
| import cuid from 'cuid'; |  | ||||||
| import { notifyClients } from "~/utils/notifyClients"; |  | ||||||
| 
 | 
 | ||||||
| export const config = { | export const config = { | ||||||
|   api: { |   api: { | ||||||
| @ -24,9 +22,7 @@ export async function POST(req: Request) { | |||||||
|   await ensureBucketExists(bucketName); |   await ensureBucketExists(bucketName); | ||||||
| 
 | 
 | ||||||
|   return new Promise<Response>((resolve, reject) => { |   return new Promise<Response>((resolve, reject) => { | ||||||
|     const busboy = Busboy({ |     const busboy = Busboy({ headers: { "content-type": req.headers.get("content-type") ?? "" } }); | ||||||
|       headers: { "content-type": req.headers.get("content-type") ?? "" }, |  | ||||||
|     }); |  | ||||||
|     let fileName = ""; |     let fileName = ""; | ||||||
|     let fileBuffer = Buffer.alloc(0); |     let fileBuffer = Buffer.alloc(0); | ||||||
| 
 | 
 | ||||||
| @ -42,11 +38,8 @@ export async function POST(req: Request) { | |||||||
|         fileBuffer = Buffer.concat(chunks); |         fileBuffer = Buffer.concat(chunks); | ||||||
| 
 | 
 | ||||||
|         // Generate a unique ID for the file
 |         // Generate a unique ID for the file
 | ||||||
|         const fileId = session.user.id + "-" + cuid() |         const fileId = crypto.randomUUID(); | ||||||
|         const objectName = `${fileId}-${fileName}`; |         const objectName = `${fileId}-${fileName}`; | ||||||
|         // Change UUID to CUID
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
|         try { |         try { | ||||||
|           // Upload the file to MinIO
 |           // Upload the file to MinIO
 | ||||||
| @ -59,19 +52,12 @@ export async function POST(req: Request) { | |||||||
|               url: `/share?id=${fileId}`, |               url: `/share?id=${fileId}`, | ||||||
|               name: fileName, |               name: fileName, | ||||||
|               size: fileBuffer.length, |               size: fileBuffer.length, | ||||||
|               extension: getFileType(fileName), |               extension: info.mimeType, | ||||||
|               uploadedById: session.user.id, |               uploadedById: session.user.id, | ||||||
|             }, |             }, | ||||||
|           }); |           }); | ||||||
|           notifyClients({ type: "file-added", fileId: fileId }); |  | ||||||
| 
 | 
 | ||||||
|           resolve( |           resolve(NextResponse.json({ message: "File uploaded successfully", file: newFile })); | ||||||
|             NextResponse.json({ |  | ||||||
|               message: "File uploaded successfully", |  | ||||||
|               file: newFile, |  | ||||||
|               fileId: fileId, |  | ||||||
|             }), |  | ||||||
|           ); |  | ||||||
|         } catch (error) { |         } catch (error) { | ||||||
|           console.error("Error uploading file to MinIO:", error); |           console.error("Error uploading file to MinIO:", error); | ||||||
|           reject(new Error("Failed to upload file")); |           reject(new Error("Failed to upload file")); | ||||||
| @ -100,4 +86,4 @@ export async function POST(req: Request) { | |||||||
|       nodeStream.pipe(busboy); |       nodeStream.pipe(busboy); | ||||||
|     } |     } | ||||||
|   }); |   }); | ||||||
| } | } | ||||||
							
								
								
									
										1
									
								
								src/app/generated/prisma-client/client.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								src/app/generated/prisma-client/client.d.ts
									
									
									
									
										vendored
									
									
								
							| @ -1 +0,0 @@ | |||||||
| export * from "./index" |  | ||||||
| @ -1,4 +0,0 @@ | |||||||
| 
 |  | ||||||
| /* !!! This is code generated by Prisma. Do not edit directly. !!! |  | ||||||
| /* eslint-disable */ |  | ||||||
| module.exports = { ...require('.') } |  | ||||||
							
								
								
									
										1
									
								
								src/app/generated/prisma-client/default.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								src/app/generated/prisma-client/default.d.ts
									
									
									
									
										vendored
									
									
								
							| @ -1 +0,0 @@ | |||||||
| export * from "./index" |  | ||||||
| @ -1,4 +0,0 @@ | |||||||
| 
 |  | ||||||
| /* !!! This is code generated by Prisma. Do not edit directly. !!! |  | ||||||
| /* eslint-disable */ |  | ||||||
| module.exports = { ...require('.') } |  | ||||||
							
								
								
									
										1
									
								
								src/app/generated/prisma-client/edge.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								src/app/generated/prisma-client/edge.d.ts
									
									
									
									
										vendored
									
									
								
							| @ -1 +0,0 @@ | |||||||
| export * from "./default" |  | ||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -1,225 +0,0 @@ | |||||||
| 
 |  | ||||||
| /* !!! This is code generated by Prisma. Do not edit directly. !!! |  | ||||||
| /* eslint-disable */ |  | ||||||
| 
 |  | ||||||
| Object.defineProperty(exports, "__esModule", { value: true }); |  | ||||||
| 
 |  | ||||||
| const { |  | ||||||
|   Decimal, |  | ||||||
|   objectEnumValues, |  | ||||||
|   makeStrictEnum, |  | ||||||
|   Public, |  | ||||||
|   getRuntime, |  | ||||||
|   skip |  | ||||||
| } = require('./runtime/index-browser.js') |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| const Prisma = {} |  | ||||||
| 
 |  | ||||||
| exports.Prisma = Prisma |  | ||||||
| exports.$Enums = {} |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Prisma Client JS version: 6.8.2 |  | ||||||
|  * Query Engine version: 2060c79ba17c6bb9f5823312b6f6b7f4a845738e |  | ||||||
|  */ |  | ||||||
| Prisma.prismaVersion = { |  | ||||||
|   client: "6.8.2", |  | ||||||
|   engine: "2060c79ba17c6bb9f5823312b6f6b7f4a845738e" |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| Prisma.PrismaClientKnownRequestError = () => { |  | ||||||
|   const runtimeName = getRuntime().prettyName; |  | ||||||
|   throw new Error(`PrismaClientKnownRequestError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
 |  | ||||||
| In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
 |  | ||||||
| )}; |  | ||||||
| Prisma.PrismaClientUnknownRequestError = () => { |  | ||||||
|   const runtimeName = getRuntime().prettyName; |  | ||||||
|   throw new Error(`PrismaClientUnknownRequestError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
 |  | ||||||
| In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
 |  | ||||||
| )} |  | ||||||
| Prisma.PrismaClientRustPanicError = () => { |  | ||||||
|   const runtimeName = getRuntime().prettyName; |  | ||||||
|   throw new Error(`PrismaClientRustPanicError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
 |  | ||||||
| In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
 |  | ||||||
| )} |  | ||||||
| Prisma.PrismaClientInitializationError = () => { |  | ||||||
|   const runtimeName = getRuntime().prettyName; |  | ||||||
|   throw new Error(`PrismaClientInitializationError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
 |  | ||||||
| In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
 |  | ||||||
| )} |  | ||||||
| Prisma.PrismaClientValidationError = () => { |  | ||||||
|   const runtimeName = getRuntime().prettyName; |  | ||||||
|   throw new Error(`PrismaClientValidationError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
 |  | ||||||
| In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
 |  | ||||||
| )} |  | ||||||
| Prisma.Decimal = Decimal |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Re-export of sql-template-tag |  | ||||||
|  */ |  | ||||||
| Prisma.sql = () => { |  | ||||||
|   const runtimeName = getRuntime().prettyName; |  | ||||||
|   throw new Error(`sqltag is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
 |  | ||||||
| In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
 |  | ||||||
| )} |  | ||||||
| Prisma.empty = () => { |  | ||||||
|   const runtimeName = getRuntime().prettyName; |  | ||||||
|   throw new Error(`empty is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
 |  | ||||||
| In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
 |  | ||||||
| )} |  | ||||||
| Prisma.join = () => { |  | ||||||
|   const runtimeName = getRuntime().prettyName; |  | ||||||
|   throw new Error(`join is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
 |  | ||||||
| In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
 |  | ||||||
| )} |  | ||||||
| Prisma.raw = () => { |  | ||||||
|   const runtimeName = getRuntime().prettyName; |  | ||||||
|   throw new Error(`raw is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
 |  | ||||||
| In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
 |  | ||||||
| )} |  | ||||||
| Prisma.validator = Public.validator |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
| * Extensions |  | ||||||
| */ |  | ||||||
| Prisma.getExtensionContext = () => { |  | ||||||
|   const runtimeName = getRuntime().prettyName; |  | ||||||
|   throw new Error(`Extensions.getExtensionContext is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
 |  | ||||||
| In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
 |  | ||||||
| )} |  | ||||||
| Prisma.defineExtension = () => { |  | ||||||
|   const runtimeName = getRuntime().prettyName; |  | ||||||
|   throw new Error(`Extensions.defineExtension is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
 |  | ||||||
| In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
 |  | ||||||
| )} |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Shorthand utilities for JSON filtering |  | ||||||
|  */ |  | ||||||
| Prisma.DbNull = objectEnumValues.instances.DbNull |  | ||||||
| Prisma.JsonNull = objectEnumValues.instances.JsonNull |  | ||||||
| Prisma.AnyNull = objectEnumValues.instances.AnyNull |  | ||||||
| 
 |  | ||||||
| Prisma.NullTypes = { |  | ||||||
|   DbNull: objectEnumValues.classes.DbNull, |  | ||||||
|   JsonNull: objectEnumValues.classes.JsonNull, |  | ||||||
|   AnyNull: objectEnumValues.classes.AnyNull |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Enums |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| exports.Prisma.TransactionIsolationLevel = makeStrictEnum({ |  | ||||||
|   ReadUncommitted: 'ReadUncommitted', |  | ||||||
|   ReadCommitted: 'ReadCommitted', |  | ||||||
|   RepeatableRead: 'RepeatableRead', |  | ||||||
|   Serializable: 'Serializable' |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| exports.Prisma.AccountScalarFieldEnum = { |  | ||||||
|   id: 'id', |  | ||||||
|   userId: 'userId', |  | ||||||
|   type: 'type', |  | ||||||
|   provider: 'provider', |  | ||||||
|   providerAccountId: 'providerAccountId', |  | ||||||
|   refresh_token: 'refresh_token', |  | ||||||
|   access_token: 'access_token', |  | ||||||
|   expires_at: 'expires_at', |  | ||||||
|   token_type: 'token_type', |  | ||||||
|   scope: 'scope', |  | ||||||
|   id_token: 'id_token', |  | ||||||
|   session_state: 'session_state', |  | ||||||
|   refresh_token_expires_in: 'refresh_token_expires_in' |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| exports.Prisma.SessionScalarFieldEnum = { |  | ||||||
|   id: 'id', |  | ||||||
|   sessionToken: 'sessionToken', |  | ||||||
|   userId: 'userId', |  | ||||||
|   expires: 'expires' |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| exports.Prisma.UserScalarFieldEnum = { |  | ||||||
|   id: 'id', |  | ||||||
|   name: 'name', |  | ||||||
|   email: 'email', |  | ||||||
|   emailVerified: 'emailVerified', |  | ||||||
|   image: 'image' |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| exports.Prisma.VerificationTokenScalarFieldEnum = { |  | ||||||
|   identifier: 'identifier', |  | ||||||
|   token: 'token', |  | ||||||
|   expires: 'expires' |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| exports.Prisma.FileScalarFieldEnum = { |  | ||||||
|   id: 'id', |  | ||||||
|   url: 'url', |  | ||||||
|   name: 'name', |  | ||||||
|   size: 'size', |  | ||||||
|   extension: 'extension', |  | ||||||
|   uploadDate: 'uploadDate', |  | ||||||
|   description: 'description', |  | ||||||
|   uploadedById: 'uploadedById', |  | ||||||
|   public: 'public' |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| exports.Prisma.SortOrder = { |  | ||||||
|   asc: 'asc', |  | ||||||
|   desc: 'desc' |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| exports.Prisma.QueryMode = { |  | ||||||
|   default: 'default', |  | ||||||
|   insensitive: 'insensitive' |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| exports.Prisma.NullsOrder = { |  | ||||||
|   first: 'first', |  | ||||||
|   last: 'last' |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| exports.Prisma.ModelName = { |  | ||||||
|   Account: 'Account', |  | ||||||
|   Session: 'Session', |  | ||||||
|   User: 'User', |  | ||||||
|   VerificationToken: 'VerificationToken', |  | ||||||
|   File: 'File' |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * This is a stub Prisma Client that will error at runtime if called. |  | ||||||
|  */ |  | ||||||
| class PrismaClient { |  | ||||||
|   constructor() { |  | ||||||
|     return new Proxy(this, { |  | ||||||
|       get(target, prop) { |  | ||||||
|         let message |  | ||||||
|         const runtime = getRuntime() |  | ||||||
|         if (runtime.isEdge) { |  | ||||||
|           message = `PrismaClient is not configured to run in ${runtime.prettyName}. In order to run Prisma Client on edge runtime, either:
 |  | ||||||
| - Use Prisma Accelerate: https://pris.ly/d/accelerate
 |  | ||||||
| - Use Driver Adapters: https://pris.ly/d/driver-adapters
 |  | ||||||
| `;
 |  | ||||||
|         } else { |  | ||||||
|           message = 'PrismaClient is unable to run in this browser environment, or has been bundled for the browser (running in `' + runtime.prettyName + '`).' |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         message += ` |  | ||||||
| If this is unexpected, please open an issue: https://pris.ly/prisma-prisma-bug-report`
 |  | ||||||
| 
 |  | ||||||
|         throw new Error(message) |  | ||||||
|       } |  | ||||||
|     }) |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| exports.PrismaClient = PrismaClient |  | ||||||
| 
 |  | ||||||
| Object.assign(exports, Prisma) |  | ||||||
							
								
								
									
										8947
									
								
								src/app/generated/prisma-client/index.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8947
									
								
								src/app/generated/prisma-client/index.d.ts
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -1,140 +0,0 @@ | |||||||
| { |  | ||||||
|   "name": "prisma-client-08d22f6c857ed95dda3e967008d87d351c30e87c75486e96dad4c24294f1763e", |  | ||||||
|   "main": "index.js", |  | ||||||
|   "types": "index.d.ts", |  | ||||||
|   "browser": "index-browser.js", |  | ||||||
|   "exports": { |  | ||||||
|     "./client": { |  | ||||||
|       "require": { |  | ||||||
|         "node": "./index.js", |  | ||||||
|         "edge-light": "./wasm.js", |  | ||||||
|         "workerd": "./wasm.js", |  | ||||||
|         "worker": "./wasm.js", |  | ||||||
|         "browser": "./index-browser.js", |  | ||||||
|         "default": "./index.js" |  | ||||||
|       }, |  | ||||||
|       "import": { |  | ||||||
|         "node": "./index.js", |  | ||||||
|         "edge-light": "./wasm.js", |  | ||||||
|         "workerd": "./wasm.js", |  | ||||||
|         "worker": "./wasm.js", |  | ||||||
|         "browser": "./index-browser.js", |  | ||||||
|         "default": "./index.js" |  | ||||||
|       }, |  | ||||||
|       "default": "./index.js" |  | ||||||
|     }, |  | ||||||
|     "./package.json": "./package.json", |  | ||||||
|     ".": { |  | ||||||
|       "require": { |  | ||||||
|         "node": "./index.js", |  | ||||||
|         "edge-light": "./wasm.js", |  | ||||||
|         "workerd": "./wasm.js", |  | ||||||
|         "worker": "./wasm.js", |  | ||||||
|         "browser": "./index-browser.js", |  | ||||||
|         "default": "./index.js" |  | ||||||
|       }, |  | ||||||
|       "import": { |  | ||||||
|         "node": "./index.js", |  | ||||||
|         "edge-light": "./wasm.js", |  | ||||||
|         "workerd": "./wasm.js", |  | ||||||
|         "worker": "./wasm.js", |  | ||||||
|         "browser": "./index-browser.js", |  | ||||||
|         "default": "./index.js" |  | ||||||
|       }, |  | ||||||
|       "default": "./index.js" |  | ||||||
|     }, |  | ||||||
|     "./edge": { |  | ||||||
|       "types": "./edge.d.ts", |  | ||||||
|       "require": "./edge.js", |  | ||||||
|       "import": "./edge.js", |  | ||||||
|       "default": "./edge.js" |  | ||||||
|     }, |  | ||||||
|     "./react-native": { |  | ||||||
|       "types": "./react-native.d.ts", |  | ||||||
|       "require": "./react-native.js", |  | ||||||
|       "import": "./react-native.js", |  | ||||||
|       "default": "./react-native.js" |  | ||||||
|     }, |  | ||||||
|     "./extension": { |  | ||||||
|       "types": "./extension.d.ts", |  | ||||||
|       "require": "./extension.js", |  | ||||||
|       "import": "./extension.js", |  | ||||||
|       "default": "./extension.js" |  | ||||||
|     }, |  | ||||||
|     "./index-browser": { |  | ||||||
|       "types": "./index.d.ts", |  | ||||||
|       "require": "./index-browser.js", |  | ||||||
|       "import": "./index-browser.js", |  | ||||||
|       "default": "./index-browser.js" |  | ||||||
|     }, |  | ||||||
|     "./index": { |  | ||||||
|       "types": "./index.d.ts", |  | ||||||
|       "require": "./index.js", |  | ||||||
|       "import": "./index.js", |  | ||||||
|       "default": "./index.js" |  | ||||||
|     }, |  | ||||||
|     "./wasm": { |  | ||||||
|       "types": "./wasm.d.ts", |  | ||||||
|       "require": "./wasm.js", |  | ||||||
|       "import": "./wasm.mjs", |  | ||||||
|       "default": "./wasm.mjs" |  | ||||||
|     }, |  | ||||||
|     "./runtime/client": { |  | ||||||
|       "types": "./runtime/client.d.ts", |  | ||||||
|       "require": "./runtime/client.js", |  | ||||||
|       "import": "./runtime/client.mjs", |  | ||||||
|       "default": "./runtime/client.mjs" |  | ||||||
|     }, |  | ||||||
|     "./runtime/library": { |  | ||||||
|       "types": "./runtime/library.d.ts", |  | ||||||
|       "require": "./runtime/library.js", |  | ||||||
|       "import": "./runtime/library.mjs", |  | ||||||
|       "default": "./runtime/library.mjs" |  | ||||||
|     }, |  | ||||||
|     "./runtime/binary": { |  | ||||||
|       "types": "./runtime/binary.d.ts", |  | ||||||
|       "require": "./runtime/binary.js", |  | ||||||
|       "import": "./runtime/binary.mjs", |  | ||||||
|       "default": "./runtime/binary.mjs" |  | ||||||
|     }, |  | ||||||
|     "./runtime/wasm": { |  | ||||||
|       "types": "./runtime/wasm.d.ts", |  | ||||||
|       "require": "./runtime/wasm.js", |  | ||||||
|       "import": "./runtime/wasm.mjs", |  | ||||||
|       "default": "./runtime/wasm.mjs" |  | ||||||
|     }, |  | ||||||
|     "./runtime/edge": { |  | ||||||
|       "types": "./runtime/edge.d.ts", |  | ||||||
|       "require": "./runtime/edge.js", |  | ||||||
|       "import": "./runtime/edge-esm.js", |  | ||||||
|       "default": "./runtime/edge-esm.js" |  | ||||||
|     }, |  | ||||||
|     "./runtime/react-native": { |  | ||||||
|       "types": "./runtime/react-native.d.ts", |  | ||||||
|       "require": "./runtime/react-native.js", |  | ||||||
|       "import": "./runtime/react-native.js", |  | ||||||
|       "default": "./runtime/react-native.js" |  | ||||||
|     }, |  | ||||||
|     "./generator-build": { |  | ||||||
|       "require": "./generator-build/index.js", |  | ||||||
|       "import": "./generator-build/index.js", |  | ||||||
|       "default": "./generator-build/index.js" |  | ||||||
|     }, |  | ||||||
|     "./sql": { |  | ||||||
|       "require": { |  | ||||||
|         "types": "./sql.d.ts", |  | ||||||
|         "node": "./sql.js", |  | ||||||
|         "default": "./sql.js" |  | ||||||
|       }, |  | ||||||
|       "import": { |  | ||||||
|         "types": "./sql.d.ts", |  | ||||||
|         "node": "./sql.mjs", |  | ||||||
|         "default": "./sql.mjs" |  | ||||||
|       }, |  | ||||||
|       "default": "./sql.js" |  | ||||||
|     }, |  | ||||||
|     "./*": "./*" |  | ||||||
|   }, |  | ||||||
|   "version": "6.8.2", |  | ||||||
|   "sideEffects": false |  | ||||||
| } |  | ||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -1,370 +0,0 @@ | |||||||
| declare class AnyNull extends NullTypesEnumValue { |  | ||||||
|     #private; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| declare type Args<T, F extends Operation> = T extends { |  | ||||||
|     [K: symbol]: { |  | ||||||
|         types: { |  | ||||||
|             operations: { |  | ||||||
|                 [K in F]: { |  | ||||||
|                     args: any; |  | ||||||
|                 }; |  | ||||||
|             }; |  | ||||||
|         }; |  | ||||||
|     }; |  | ||||||
| } ? T[symbol]['types']['operations'][F]['args'] : any; |  | ||||||
| 
 |  | ||||||
| declare class DbNull extends NullTypesEnumValue { |  | ||||||
|     #private; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export declare function Decimal(n: Decimal.Value): Decimal; |  | ||||||
| 
 |  | ||||||
| export declare namespace Decimal { |  | ||||||
|     export type Constructor = typeof Decimal; |  | ||||||
|     export type Instance = Decimal; |  | ||||||
|     export type Rounding = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8; |  | ||||||
|     export type Modulo = Rounding | 9; |  | ||||||
|     export type Value = string | number | Decimal; |  | ||||||
| 
 |  | ||||||
|     // http://mikemcl.github.io/decimal.js/#constructor-properties
 |  | ||||||
|     export interface Config { |  | ||||||
|         precision?: number; |  | ||||||
|         rounding?: Rounding; |  | ||||||
|         toExpNeg?: number; |  | ||||||
|         toExpPos?: number; |  | ||||||
|         minE?: number; |  | ||||||
|         maxE?: number; |  | ||||||
|         crypto?: boolean; |  | ||||||
|         modulo?: Modulo; |  | ||||||
|         defaults?: boolean; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export declare class Decimal { |  | ||||||
|     readonly d: number[]; |  | ||||||
|     readonly e: number; |  | ||||||
|     readonly s: number; |  | ||||||
| 
 |  | ||||||
|     constructor(n: Decimal.Value); |  | ||||||
| 
 |  | ||||||
|     absoluteValue(): Decimal; |  | ||||||
|     abs(): Decimal; |  | ||||||
| 
 |  | ||||||
|     ceil(): Decimal; |  | ||||||
| 
 |  | ||||||
|     clampedTo(min: Decimal.Value, max: Decimal.Value): Decimal; |  | ||||||
|     clamp(min: Decimal.Value, max: Decimal.Value): Decimal; |  | ||||||
| 
 |  | ||||||
|     comparedTo(n: Decimal.Value): number; |  | ||||||
|     cmp(n: Decimal.Value): number; |  | ||||||
| 
 |  | ||||||
|     cosine(): Decimal; |  | ||||||
|     cos(): Decimal; |  | ||||||
| 
 |  | ||||||
|     cubeRoot(): Decimal; |  | ||||||
|     cbrt(): Decimal; |  | ||||||
| 
 |  | ||||||
|     decimalPlaces(): number; |  | ||||||
|     dp(): number; |  | ||||||
| 
 |  | ||||||
|     dividedBy(n: Decimal.Value): Decimal; |  | ||||||
|     div(n: Decimal.Value): Decimal; |  | ||||||
| 
 |  | ||||||
|     dividedToIntegerBy(n: Decimal.Value): Decimal; |  | ||||||
|     divToInt(n: Decimal.Value): Decimal; |  | ||||||
| 
 |  | ||||||
|     equals(n: Decimal.Value): boolean; |  | ||||||
|     eq(n: Decimal.Value): boolean; |  | ||||||
| 
 |  | ||||||
|     floor(): Decimal; |  | ||||||
| 
 |  | ||||||
|     greaterThan(n: Decimal.Value): boolean; |  | ||||||
|     gt(n: Decimal.Value): boolean; |  | ||||||
| 
 |  | ||||||
|     greaterThanOrEqualTo(n: Decimal.Value): boolean; |  | ||||||
|     gte(n: Decimal.Value): boolean; |  | ||||||
| 
 |  | ||||||
|     hyperbolicCosine(): Decimal; |  | ||||||
|     cosh(): Decimal; |  | ||||||
| 
 |  | ||||||
|     hyperbolicSine(): Decimal; |  | ||||||
|     sinh(): Decimal; |  | ||||||
| 
 |  | ||||||
|     hyperbolicTangent(): Decimal; |  | ||||||
|     tanh(): Decimal; |  | ||||||
| 
 |  | ||||||
|     inverseCosine(): Decimal; |  | ||||||
|     acos(): Decimal; |  | ||||||
| 
 |  | ||||||
|     inverseHyperbolicCosine(): Decimal; |  | ||||||
|     acosh(): Decimal; |  | ||||||
| 
 |  | ||||||
|     inverseHyperbolicSine(): Decimal; |  | ||||||
|     asinh(): Decimal; |  | ||||||
| 
 |  | ||||||
|     inverseHyperbolicTangent(): Decimal; |  | ||||||
|     atanh(): Decimal; |  | ||||||
| 
 |  | ||||||
|     inverseSine(): Decimal; |  | ||||||
|     asin(): Decimal; |  | ||||||
| 
 |  | ||||||
|     inverseTangent(): Decimal; |  | ||||||
|     atan(): Decimal; |  | ||||||
| 
 |  | ||||||
|     isFinite(): boolean; |  | ||||||
| 
 |  | ||||||
|     isInteger(): boolean; |  | ||||||
|     isInt(): boolean; |  | ||||||
| 
 |  | ||||||
|     isNaN(): boolean; |  | ||||||
| 
 |  | ||||||
|     isNegative(): boolean; |  | ||||||
|     isNeg(): boolean; |  | ||||||
| 
 |  | ||||||
|     isPositive(): boolean; |  | ||||||
|     isPos(): boolean; |  | ||||||
| 
 |  | ||||||
|     isZero(): boolean; |  | ||||||
| 
 |  | ||||||
|     lessThan(n: Decimal.Value): boolean; |  | ||||||
|     lt(n: Decimal.Value): boolean; |  | ||||||
| 
 |  | ||||||
|     lessThanOrEqualTo(n: Decimal.Value): boolean; |  | ||||||
|     lte(n: Decimal.Value): boolean; |  | ||||||
| 
 |  | ||||||
|     logarithm(n?: Decimal.Value): Decimal; |  | ||||||
|     log(n?: Decimal.Value): Decimal; |  | ||||||
| 
 |  | ||||||
|     minus(n: Decimal.Value): Decimal; |  | ||||||
|     sub(n: Decimal.Value): Decimal; |  | ||||||
| 
 |  | ||||||
|     modulo(n: Decimal.Value): Decimal; |  | ||||||
|     mod(n: Decimal.Value): Decimal; |  | ||||||
| 
 |  | ||||||
|     naturalExponential(): Decimal; |  | ||||||
|     exp(): Decimal; |  | ||||||
| 
 |  | ||||||
|     naturalLogarithm(): Decimal; |  | ||||||
|     ln(): Decimal; |  | ||||||
| 
 |  | ||||||
|     negated(): Decimal; |  | ||||||
|     neg(): Decimal; |  | ||||||
| 
 |  | ||||||
|     plus(n: Decimal.Value): Decimal; |  | ||||||
|     add(n: Decimal.Value): Decimal; |  | ||||||
| 
 |  | ||||||
|     precision(includeZeros?: boolean): number; |  | ||||||
|     sd(includeZeros?: boolean): number; |  | ||||||
| 
 |  | ||||||
|     round(): Decimal; |  | ||||||
| 
 |  | ||||||
|     sine() : Decimal; |  | ||||||
|     sin() : Decimal; |  | ||||||
| 
 |  | ||||||
|     squareRoot(): Decimal; |  | ||||||
|     sqrt(): Decimal; |  | ||||||
| 
 |  | ||||||
|     tangent() : Decimal; |  | ||||||
|     tan() : Decimal; |  | ||||||
| 
 |  | ||||||
|     times(n: Decimal.Value): Decimal; |  | ||||||
|     mul(n: Decimal.Value) : Decimal; |  | ||||||
| 
 |  | ||||||
|     toBinary(significantDigits?: number): string; |  | ||||||
|     toBinary(significantDigits: number, rounding: Decimal.Rounding): string; |  | ||||||
| 
 |  | ||||||
|     toDecimalPlaces(decimalPlaces?: number): Decimal; |  | ||||||
|     toDecimalPlaces(decimalPlaces: number, rounding: Decimal.Rounding): Decimal; |  | ||||||
|     toDP(decimalPlaces?: number): Decimal; |  | ||||||
|     toDP(decimalPlaces: number, rounding: Decimal.Rounding): Decimal; |  | ||||||
| 
 |  | ||||||
|     toExponential(decimalPlaces?: number): string; |  | ||||||
|     toExponential(decimalPlaces: number, rounding: Decimal.Rounding): string; |  | ||||||
| 
 |  | ||||||
|     toFixed(decimalPlaces?: number): string; |  | ||||||
|     toFixed(decimalPlaces: number, rounding: Decimal.Rounding): string; |  | ||||||
| 
 |  | ||||||
|     toFraction(max_denominator?: Decimal.Value): Decimal[]; |  | ||||||
| 
 |  | ||||||
|     toHexadecimal(significantDigits?: number): string; |  | ||||||
|     toHexadecimal(significantDigits: number, rounding: Decimal.Rounding): string; |  | ||||||
|     toHex(significantDigits?: number): string; |  | ||||||
|     toHex(significantDigits: number, rounding?: Decimal.Rounding): string; |  | ||||||
| 
 |  | ||||||
|     toJSON(): string; |  | ||||||
| 
 |  | ||||||
|     toNearest(n: Decimal.Value, rounding?: Decimal.Rounding): Decimal; |  | ||||||
| 
 |  | ||||||
|     toNumber(): number; |  | ||||||
| 
 |  | ||||||
|     toOctal(significantDigits?: number): string; |  | ||||||
|     toOctal(significantDigits: number, rounding: Decimal.Rounding): string; |  | ||||||
| 
 |  | ||||||
|     toPower(n: Decimal.Value): Decimal; |  | ||||||
|     pow(n: Decimal.Value): Decimal; |  | ||||||
| 
 |  | ||||||
|     toPrecision(significantDigits?: number): string; |  | ||||||
|     toPrecision(significantDigits: number, rounding: Decimal.Rounding): string; |  | ||||||
| 
 |  | ||||||
|     toSignificantDigits(significantDigits?: number): Decimal; |  | ||||||
|     toSignificantDigits(significantDigits: number, rounding: Decimal.Rounding): Decimal; |  | ||||||
|     toSD(significantDigits?: number): Decimal; |  | ||||||
|     toSD(significantDigits: number, rounding: Decimal.Rounding): Decimal; |  | ||||||
| 
 |  | ||||||
|     toString(): string; |  | ||||||
| 
 |  | ||||||
|     truncated(): Decimal; |  | ||||||
|     trunc(): Decimal; |  | ||||||
| 
 |  | ||||||
|     valueOf(): string; |  | ||||||
| 
 |  | ||||||
|     static abs(n: Decimal.Value): Decimal; |  | ||||||
|     static acos(n: Decimal.Value): Decimal; |  | ||||||
|     static acosh(n: Decimal.Value): Decimal; |  | ||||||
|     static add(x: Decimal.Value, y: Decimal.Value): Decimal; |  | ||||||
|     static asin(n: Decimal.Value): Decimal; |  | ||||||
|     static asinh(n: Decimal.Value): Decimal; |  | ||||||
|     static atan(n: Decimal.Value): Decimal; |  | ||||||
|     static atanh(n: Decimal.Value): Decimal; |  | ||||||
|     static atan2(y: Decimal.Value, x: Decimal.Value): Decimal; |  | ||||||
|     static cbrt(n: Decimal.Value): Decimal; |  | ||||||
|     static ceil(n: Decimal.Value): Decimal; |  | ||||||
|     static clamp(n: Decimal.Value, min: Decimal.Value, max: Decimal.Value): Decimal; |  | ||||||
|     static clone(object?: Decimal.Config): Decimal.Constructor; |  | ||||||
|     static config(object: Decimal.Config): Decimal.Constructor; |  | ||||||
|     static cos(n: Decimal.Value): Decimal; |  | ||||||
|     static cosh(n: Decimal.Value): Decimal; |  | ||||||
|     static div(x: Decimal.Value, y: Decimal.Value): Decimal; |  | ||||||
|     static exp(n: Decimal.Value): Decimal; |  | ||||||
|     static floor(n: Decimal.Value): Decimal; |  | ||||||
|     static hypot(...n: Decimal.Value[]): Decimal; |  | ||||||
|     static isDecimal(object: any): object is Decimal; |  | ||||||
|     static ln(n: Decimal.Value): Decimal; |  | ||||||
|     static log(n: Decimal.Value, base?: Decimal.Value): Decimal; |  | ||||||
|     static log2(n: Decimal.Value): Decimal; |  | ||||||
|     static log10(n: Decimal.Value): Decimal; |  | ||||||
|     static max(...n: Decimal.Value[]): Decimal; |  | ||||||
|     static min(...n: Decimal.Value[]): Decimal; |  | ||||||
|     static mod(x: Decimal.Value, y: Decimal.Value): Decimal; |  | ||||||
|     static mul(x: Decimal.Value, y: Decimal.Value): Decimal; |  | ||||||
|     static noConflict(): Decimal.Constructor;   // Browser only
 |  | ||||||
|     static pow(base: Decimal.Value, exponent: Decimal.Value): Decimal; |  | ||||||
|     static random(significantDigits?: number): Decimal; |  | ||||||
|     static round(n: Decimal.Value): Decimal; |  | ||||||
|     static set(object: Decimal.Config): Decimal.Constructor; |  | ||||||
|     static sign(n: Decimal.Value): number; |  | ||||||
|     static sin(n: Decimal.Value): Decimal; |  | ||||||
|     static sinh(n: Decimal.Value): Decimal; |  | ||||||
|     static sqrt(n: Decimal.Value): Decimal; |  | ||||||
|     static sub(x: Decimal.Value, y: Decimal.Value): Decimal; |  | ||||||
|     static sum(...n: Decimal.Value[]): Decimal; |  | ||||||
|     static tan(n: Decimal.Value): Decimal; |  | ||||||
|     static tanh(n: Decimal.Value): Decimal; |  | ||||||
|     static trunc(n: Decimal.Value): Decimal; |  | ||||||
| 
 |  | ||||||
|     static readonly default?: Decimal.Constructor; |  | ||||||
|     static readonly Decimal?: Decimal.Constructor; |  | ||||||
| 
 |  | ||||||
|     static readonly precision: number; |  | ||||||
|     static readonly rounding: Decimal.Rounding; |  | ||||||
|     static readonly toExpNeg: number; |  | ||||||
|     static readonly toExpPos: number; |  | ||||||
|     static readonly minE: number; |  | ||||||
|     static readonly maxE: number; |  | ||||||
|     static readonly crypto: boolean; |  | ||||||
|     static readonly modulo: Decimal.Modulo; |  | ||||||
| 
 |  | ||||||
|     static readonly ROUND_UP: 0; |  | ||||||
|     static readonly ROUND_DOWN: 1; |  | ||||||
|     static readonly ROUND_CEIL: 2; |  | ||||||
|     static readonly ROUND_FLOOR: 3; |  | ||||||
|     static readonly ROUND_HALF_UP: 4; |  | ||||||
|     static readonly ROUND_HALF_DOWN: 5; |  | ||||||
|     static readonly ROUND_HALF_EVEN: 6; |  | ||||||
|     static readonly ROUND_HALF_CEIL: 7; |  | ||||||
|     static readonly ROUND_HALF_FLOOR: 8; |  | ||||||
|     static readonly EUCLID: 9; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| declare type Exact<A, W> = (A extends unknown ? (W extends A ? { |  | ||||||
|     [K in keyof A]: Exact<A[K], W[K]>; |  | ||||||
| } : W) : never) | (A extends Narrowable ? A : never); |  | ||||||
| 
 |  | ||||||
| export declare function getRuntime(): GetRuntimeOutput; |  | ||||||
| 
 |  | ||||||
| declare type GetRuntimeOutput = { |  | ||||||
|     id: RuntimeName; |  | ||||||
|     prettyName: string; |  | ||||||
|     isEdge: boolean; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| declare class JsonNull extends NullTypesEnumValue { |  | ||||||
|     #private; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Generates more strict variant of an enum which, unlike regular enum, |  | ||||||
|  * throws on non-existing property access. This can be useful in following situations: |  | ||||||
|  * - we have an API, that accepts both `undefined` and `SomeEnumType` as an input |  | ||||||
|  * - enum values are generated dynamically from DMMF. |  | ||||||
|  * |  | ||||||
|  * In that case, if using normal enums and no compile-time typechecking, using non-existing property |  | ||||||
|  * will result in `undefined` value being used, which will be accepted. Using strict enum |  | ||||||
|  * in this case will help to have a runtime exception, telling you that you are probably doing something wrong. |  | ||||||
|  * |  | ||||||
|  * Note: if you need to check for existence of a value in the enum you can still use either |  | ||||||
|  * `in` operator or `hasOwnProperty` function. |  | ||||||
|  * |  | ||||||
|  * @param definition |  | ||||||
|  * @returns |  | ||||||
|  */ |  | ||||||
| export declare function makeStrictEnum<T extends Record<PropertyKey, string | number>>(definition: T): T; |  | ||||||
| 
 |  | ||||||
| declare type Narrowable = string | number | bigint | boolean | []; |  | ||||||
| 
 |  | ||||||
| declare class NullTypesEnumValue extends ObjectEnumValue { |  | ||||||
|     _getNamespace(): string; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Base class for unique values of object-valued enums. |  | ||||||
|  */ |  | ||||||
| declare abstract class ObjectEnumValue { |  | ||||||
|     constructor(arg?: symbol); |  | ||||||
|     abstract _getNamespace(): string; |  | ||||||
|     _getName(): string; |  | ||||||
|     toString(): string; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export declare const objectEnumValues: { |  | ||||||
|     classes: { |  | ||||||
|         DbNull: typeof DbNull; |  | ||||||
|         JsonNull: typeof JsonNull; |  | ||||||
|         AnyNull: typeof AnyNull; |  | ||||||
|     }; |  | ||||||
|     instances: { |  | ||||||
|         DbNull: DbNull; |  | ||||||
|         JsonNull: JsonNull; |  | ||||||
|         AnyNull: AnyNull; |  | ||||||
|     }; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| declare type Operation = 'findFirst' | 'findFirstOrThrow' | 'findUnique' | 'findUniqueOrThrow' | 'findMany' | 'create' | 'createMany' | 'createManyAndReturn' | 'update' | 'updateMany' | 'updateManyAndReturn' | 'upsert' | 'delete' | 'deleteMany' | 'aggregate' | 'count' | 'groupBy' | '$queryRaw' | '$executeRaw' | '$queryRawUnsafe' | '$executeRawUnsafe' | 'findRaw' | 'aggregateRaw' | '$runCommandRaw'; |  | ||||||
| 
 |  | ||||||
| declare namespace Public { |  | ||||||
|     export { |  | ||||||
|         validator |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| export { Public } |  | ||||||
| 
 |  | ||||||
| declare type RuntimeName = 'workerd' | 'deno' | 'netlify' | 'node' | 'bun' | 'edge-light' | ''; |  | ||||||
| 
 |  | ||||||
| declare function validator<V>(): <S>(select: Exact<S, V>) => S; |  | ||||||
| 
 |  | ||||||
| declare function validator<C, M extends Exclude<keyof C, `$${string}`>, O extends keyof C[M] & Operation>(client: C, model: M, operation: O): <S>(select: Exact<S, Args<C[M], O>>) => S; |  | ||||||
| 
 |  | ||||||
| declare function validator<C, M extends Exclude<keyof C, `$${string}`>, O extends keyof C[M] & Operation, P extends keyof Args<C[M], O>>(client: C, model: M, operation: O, prop: P): <S>(select: Exact<S, Args<C[M], O>[P]>) => S; |  | ||||||
| 
 |  | ||||||
| export { } |  | ||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										3647
									
								
								src/app/generated/prisma-client/runtime/library.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3647
									
								
								src/app/generated/prisma-client/runtime/library.d.ts
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -1,77 +0,0 @@ | |||||||
| // This is your Prisma schema file, |  | ||||||
| // learn more about it in the docs: https://pris.ly/d/prisma-schema |  | ||||||
| 
 |  | ||||||
| generator client { |  | ||||||
|   provider      = "prisma-client-js" |  | ||||||
|   binaryTargets = ["native", "debian-openssl-3.0.x"] |  | ||||||
|   output        = "/app/generated/prisma-client" |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| datasource db { |  | ||||||
|   provider = "postgresql" |  | ||||||
|   // NOTE: When using mysql or sqlserver, uncomment the @db.Text annotations in model Account below |  | ||||||
|   // Further reading: |  | ||||||
|   // https://next-auth.js.org/adapters/prisma#create-the-prisma-schema |  | ||||||
|   // https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference#string |  | ||||||
|   url      = env("DATABASE_URL") |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Necessary for Next auth |  | ||||||
| model Account { |  | ||||||
|   id                       String  @id @default(cuid()) |  | ||||||
|   userId                   String |  | ||||||
|   type                     String |  | ||||||
|   provider                 String |  | ||||||
|   providerAccountId        String |  | ||||||
|   refresh_token            String? @db.Text |  | ||||||
|   access_token             String? // @db.Text |  | ||||||
|   expires_at               Int? |  | ||||||
|   token_type               String? |  | ||||||
|   scope                    String? |  | ||||||
|   id_token                 String? // @db.Text |  | ||||||
|   session_state            String? |  | ||||||
|   user                     User    @relation(fields: [userId], references: [id], onDelete: Cascade) |  | ||||||
|   refresh_token_expires_in Int? |  | ||||||
| 
 |  | ||||||
|   @@unique([provider, providerAccountId]) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| model Session { |  | ||||||
|   id           String   @id @default(cuid()) |  | ||||||
|   sessionToken String   @unique |  | ||||||
|   userId       String |  | ||||||
|   expires      DateTime |  | ||||||
|   user         User     @relation(fields: [userId], references: [id], onDelete: Cascade) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| model User { |  | ||||||
|   id            String    @id @default(cuid()) |  | ||||||
|   name          String? |  | ||||||
|   email         String?   @unique |  | ||||||
|   emailVerified DateTime? |  | ||||||
|   image         String? |  | ||||||
|   accounts      Account[] |  | ||||||
|   sessions      Session[] |  | ||||||
|   files         File[] // Relation to the File model |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| model VerificationToken { |  | ||||||
|   identifier String |  | ||||||
|   token      String   @unique |  | ||||||
|   expires    DateTime |  | ||||||
| 
 |  | ||||||
|   @@unique([identifier, token]) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| model File { |  | ||||||
|   id           String   @id @default(cuid()) |  | ||||||
|   url          String |  | ||||||
|   name         String |  | ||||||
|   size         Int // Size in bytes |  | ||||||
|   extension    String |  | ||||||
|   uploadDate   DateTime @default(now()) |  | ||||||
|   description  String   @default("") |  | ||||||
|   uploadedBy   User?    @relation(fields: [uploadedById], references: [id], onDelete: SetNull) |  | ||||||
|   uploadedById String? |  | ||||||
|   public       Boolean  @default(false) // Indicates if the file is public or private |  | ||||||
| } |  | ||||||
							
								
								
									
										1
									
								
								src/app/generated/prisma-client/wasm.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								src/app/generated/prisma-client/wasm.d.ts
									
									
									
									
										vendored
									
									
								
							| @ -1 +0,0 @@ | |||||||
| export * from "./index" |  | ||||||
| @ -1,225 +0,0 @@ | |||||||
| 
 |  | ||||||
| /* !!! This is code generated by Prisma. Do not edit directly. !!! |  | ||||||
| /* eslint-disable */ |  | ||||||
| 
 |  | ||||||
| Object.defineProperty(exports, "__esModule", { value: true }); |  | ||||||
| 
 |  | ||||||
| const { |  | ||||||
|   Decimal, |  | ||||||
|   objectEnumValues, |  | ||||||
|   makeStrictEnum, |  | ||||||
|   Public, |  | ||||||
|   getRuntime, |  | ||||||
|   skip |  | ||||||
| } = require('./runtime/index-browser.js') |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| const Prisma = {} |  | ||||||
| 
 |  | ||||||
| exports.Prisma = Prisma |  | ||||||
| exports.$Enums = {} |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Prisma Client JS version: 6.8.2 |  | ||||||
|  * Query Engine version: 2060c79ba17c6bb9f5823312b6f6b7f4a845738e |  | ||||||
|  */ |  | ||||||
| Prisma.prismaVersion = { |  | ||||||
|   client: "6.8.2", |  | ||||||
|   engine: "2060c79ba17c6bb9f5823312b6f6b7f4a845738e" |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| Prisma.PrismaClientKnownRequestError = () => { |  | ||||||
|   const runtimeName = getRuntime().prettyName; |  | ||||||
|   throw new Error(`PrismaClientKnownRequestError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
 |  | ||||||
| In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
 |  | ||||||
| )}; |  | ||||||
| Prisma.PrismaClientUnknownRequestError = () => { |  | ||||||
|   const runtimeName = getRuntime().prettyName; |  | ||||||
|   throw new Error(`PrismaClientUnknownRequestError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
 |  | ||||||
| In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
 |  | ||||||
| )} |  | ||||||
| Prisma.PrismaClientRustPanicError = () => { |  | ||||||
|   const runtimeName = getRuntime().prettyName; |  | ||||||
|   throw new Error(`PrismaClientRustPanicError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
 |  | ||||||
| In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
 |  | ||||||
| )} |  | ||||||
| Prisma.PrismaClientInitializationError = () => { |  | ||||||
|   const runtimeName = getRuntime().prettyName; |  | ||||||
|   throw new Error(`PrismaClientInitializationError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
 |  | ||||||
| In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
 |  | ||||||
| )} |  | ||||||
| Prisma.PrismaClientValidationError = () => { |  | ||||||
|   const runtimeName = getRuntime().prettyName; |  | ||||||
|   throw new Error(`PrismaClientValidationError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
 |  | ||||||
| In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
 |  | ||||||
| )} |  | ||||||
| Prisma.Decimal = Decimal |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Re-export of sql-template-tag |  | ||||||
|  */ |  | ||||||
| Prisma.sql = () => { |  | ||||||
|   const runtimeName = getRuntime().prettyName; |  | ||||||
|   throw new Error(`sqltag is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
 |  | ||||||
| In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
 |  | ||||||
| )} |  | ||||||
| Prisma.empty = () => { |  | ||||||
|   const runtimeName = getRuntime().prettyName; |  | ||||||
|   throw new Error(`empty is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
 |  | ||||||
| In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
 |  | ||||||
| )} |  | ||||||
| Prisma.join = () => { |  | ||||||
|   const runtimeName = getRuntime().prettyName; |  | ||||||
|   throw new Error(`join is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
 |  | ||||||
| In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
 |  | ||||||
| )} |  | ||||||
| Prisma.raw = () => { |  | ||||||
|   const runtimeName = getRuntime().prettyName; |  | ||||||
|   throw new Error(`raw is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
 |  | ||||||
| In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
 |  | ||||||
| )} |  | ||||||
| Prisma.validator = Public.validator |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
| * Extensions |  | ||||||
| */ |  | ||||||
| Prisma.getExtensionContext = () => { |  | ||||||
|   const runtimeName = getRuntime().prettyName; |  | ||||||
|   throw new Error(`Extensions.getExtensionContext is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
 |  | ||||||
| In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
 |  | ||||||
| )} |  | ||||||
| Prisma.defineExtension = () => { |  | ||||||
|   const runtimeName = getRuntime().prettyName; |  | ||||||
|   throw new Error(`Extensions.defineExtension is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
 |  | ||||||
| In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
 |  | ||||||
| )} |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Shorthand utilities for JSON filtering |  | ||||||
|  */ |  | ||||||
| Prisma.DbNull = objectEnumValues.instances.DbNull |  | ||||||
| Prisma.JsonNull = objectEnumValues.instances.JsonNull |  | ||||||
| Prisma.AnyNull = objectEnumValues.instances.AnyNull |  | ||||||
| 
 |  | ||||||
| Prisma.NullTypes = { |  | ||||||
|   DbNull: objectEnumValues.classes.DbNull, |  | ||||||
|   JsonNull: objectEnumValues.classes.JsonNull, |  | ||||||
|   AnyNull: objectEnumValues.classes.AnyNull |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Enums |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| exports.Prisma.TransactionIsolationLevel = makeStrictEnum({ |  | ||||||
|   ReadUncommitted: 'ReadUncommitted', |  | ||||||
|   ReadCommitted: 'ReadCommitted', |  | ||||||
|   RepeatableRead: 'RepeatableRead', |  | ||||||
|   Serializable: 'Serializable' |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| exports.Prisma.AccountScalarFieldEnum = { |  | ||||||
|   id: 'id', |  | ||||||
|   userId: 'userId', |  | ||||||
|   type: 'type', |  | ||||||
|   provider: 'provider', |  | ||||||
|   providerAccountId: 'providerAccountId', |  | ||||||
|   refresh_token: 'refresh_token', |  | ||||||
|   access_token: 'access_token', |  | ||||||
|   expires_at: 'expires_at', |  | ||||||
|   token_type: 'token_type', |  | ||||||
|   scope: 'scope', |  | ||||||
|   id_token: 'id_token', |  | ||||||
|   session_state: 'session_state', |  | ||||||
|   refresh_token_expires_in: 'refresh_token_expires_in' |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| exports.Prisma.SessionScalarFieldEnum = { |  | ||||||
|   id: 'id', |  | ||||||
|   sessionToken: 'sessionToken', |  | ||||||
|   userId: 'userId', |  | ||||||
|   expires: 'expires' |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| exports.Prisma.UserScalarFieldEnum = { |  | ||||||
|   id: 'id', |  | ||||||
|   name: 'name', |  | ||||||
|   email: 'email', |  | ||||||
|   emailVerified: 'emailVerified', |  | ||||||
|   image: 'image' |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| exports.Prisma.VerificationTokenScalarFieldEnum = { |  | ||||||
|   identifier: 'identifier', |  | ||||||
|   token: 'token', |  | ||||||
|   expires: 'expires' |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| exports.Prisma.FileScalarFieldEnum = { |  | ||||||
|   id: 'id', |  | ||||||
|   url: 'url', |  | ||||||
|   name: 'name', |  | ||||||
|   size: 'size', |  | ||||||
|   extension: 'extension', |  | ||||||
|   uploadDate: 'uploadDate', |  | ||||||
|   description: 'description', |  | ||||||
|   uploadedById: 'uploadedById', |  | ||||||
|   public: 'public' |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| exports.Prisma.SortOrder = { |  | ||||||
|   asc: 'asc', |  | ||||||
|   desc: 'desc' |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| exports.Prisma.QueryMode = { |  | ||||||
|   default: 'default', |  | ||||||
|   insensitive: 'insensitive' |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| exports.Prisma.NullsOrder = { |  | ||||||
|   first: 'first', |  | ||||||
|   last: 'last' |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| exports.Prisma.ModelName = { |  | ||||||
|   Account: 'Account', |  | ||||||
|   Session: 'Session', |  | ||||||
|   User: 'User', |  | ||||||
|   VerificationToken: 'VerificationToken', |  | ||||||
|   File: 'File' |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * This is a stub Prisma Client that will error at runtime if called. |  | ||||||
|  */ |  | ||||||
| class PrismaClient { |  | ||||||
|   constructor() { |  | ||||||
|     return new Proxy(this, { |  | ||||||
|       get(target, prop) { |  | ||||||
|         let message |  | ||||||
|         const runtime = getRuntime() |  | ||||||
|         if (runtime.isEdge) { |  | ||||||
|           message = `PrismaClient is not configured to run in ${runtime.prettyName}. In order to run Prisma Client on edge runtime, either:
 |  | ||||||
| - Use Prisma Accelerate: https://pris.ly/d/accelerate
 |  | ||||||
| - Use Driver Adapters: https://pris.ly/d/driver-adapters
 |  | ||||||
| `;
 |  | ||||||
|         } else { |  | ||||||
|           message = 'PrismaClient is unable to run in this browser environment, or has been bundled for the browser (running in `' + runtime.prettyName + '`).' |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         message += ` |  | ||||||
| If this is unexpected, please open an issue: https://pris.ly/prisma-prisma-bug-report`
 |  | ||||||
| 
 |  | ||||||
|         throw new Error(message) |  | ||||||
|       } |  | ||||||
|     }) |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| exports.PrismaClient = PrismaClient |  | ||||||
| 
 |  | ||||||
| Object.assign(exports, Prisma) |  | ||||||
| @ -1,6 +0,0 @@ | |||||||
| import LoadingSkeleton from './LoadingSkeleton'; |  | ||||||
| 
 |  | ||||||
| export default function Loading() { |  | ||||||
|   // You can add any UI inside Loading, including a Skeleton.
 |  | ||||||
|   return <LoadingSkeleton /> |  | ||||||
| } |  | ||||||
							
								
								
									
										101
									
								
								src/app/page.tsx
									
									
									
									
									
								
							
							
						
						
									
										101
									
								
								src/app/page.tsx
									
									
									
									
									
								
							| @ -1,53 +1,15 @@ | |||||||
| "use client"; |  | ||||||
| 
 |  | ||||||
| import Link from "next/link"; | import Link from "next/link"; | ||||||
| import { useEffect, useState } from "react"; | import { auth } from "~/server/auth"; | ||||||
|  | import { HydrateClient } from "~/trpc/server"; | ||||||
| import FileGrid from "~/app/_components/FileGrid"; | import FileGrid from "~/app/_components/FileGrid"; | ||||||
| import UploadForm from "~/app/_components/UploadForm"; | import UploadForm from "~/app/_components/UploadForm"; | ||||||
| import { Toaster } from "react-hot-toast"; | import { Toaster } from "react-hot-toast"; | ||||||
| import { Suspense } from "react"; |  | ||||||
| import LoadingSkeleton from "./LoadingSkeleton"; |  | ||||||
| 
 | 
 | ||||||
| // Custom fallback for FileGrid
 | export default async function Home() { | ||||||
| function FileGridFallback() { |   const session = await auth(); | ||||||
|   return ( |  | ||||||
|     <div className="grid w-full max-w-4xl animate-pulse grid-cols-1 gap-6 sm:grid-cols-2 md:grid-cols-3"> |  | ||||||
|       {[...Array(6)].map((_, i) => ( |  | ||||||
|         <div key={i} className="flex flex-col items-center"> |  | ||||||
|           <span className="mb-2 text-lg text-white/60">Loading</span> |  | ||||||
|           <div className="h-32 w-full rounded bg-white/10" /> |  | ||||||
|         </div> |  | ||||||
|       ))} |  | ||||||
|     </div> |  | ||||||
|   ); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Custom fallback for UploadForm
 |  | ||||||
| function UploadFormFallback() { |  | ||||||
|   return ( |  | ||||||
|     <div className="mt-8 flex w-full max-w-md animate-pulse flex-col gap-4"> |  | ||||||
|       <div className="h-10 rounded bg-white/20" /> |  | ||||||
|       <div className="h-10 rounded bg-white/10" /> |  | ||||||
|     </div> |  | ||||||
|   ); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function Home() { |  | ||||||
|   const [session, setSession] = useState<{ user?: any } | null>(null); |  | ||||||
|   const [loading, setLoading] = useState(true); |  | ||||||
|   useEffect(() => { |  | ||||||
|     async function fetchSession() { |  | ||||||
|       setLoading(true); |  | ||||||
|       const res = await fetch("/api/auth/session"); |  | ||||||
|       const data = await res.json(); |  | ||||||
|       setSession(data); |  | ||||||
|       setLoading(false); |  | ||||||
|     } |  | ||||||
|     fetchSession(); |  | ||||||
|   }, []); |  | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <> |     <HydrateClient> | ||||||
|       <Toaster position="top-right" reverseOrder={false} /> |       <Toaster position="top-right" reverseOrder={false} /> | ||||||
|       <main className="relative flex min-h-screen flex-col items-center justify-center bg-gradient-to-b from-[#2e026d] to-[#15162c] text-white"> |       <main className="relative flex min-h-screen flex-col items-center justify-center bg-gradient-to-b from-[#2e026d] to-[#15162c] text-white"> | ||||||
|         {/* Top-right corner sign-out button */} |         {/* Top-right corner sign-out button */} | ||||||
| @ -91,59 +53,28 @@ function Home() { | |||||||
|           {/* Conditionally render FileGrid and UploadForm if the user is logged in */} |           {/* Conditionally render FileGrid and UploadForm if the user is logged in */} | ||||||
|           {session?.user ? ( |           {session?.user ? ( | ||||||
|             <> |             <> | ||||||
|               <Suspense fallback={<FileGridFallback />}> |               <FileGrid session={session} /> | ||||||
|                 <FileGrid session={session as { user: { id: string } }} /> |               <UploadForm /> | ||||||
|               </Suspense> |  | ||||||
|               <Suspense fallback={<UploadFormFallback />}> |  | ||||||
|                 <UploadForm /> |  | ||||||
|               </Suspense> |  | ||||||
|             </> |             </> | ||||||
|           ) : !loading ? ( |           ) : ( | ||||||
|             <p className="text-center text-2xl text-white"> |             <p className="text-center text-2xl text-white"> | ||||||
|               Please log in to upload and view files. |               Please log in to upload and view files. | ||||||
|             </p> |             </p> | ||||||
|           ) : null} |           )} | ||||||
|           {!session?.user && ( |           {!session?.user && ( | ||||||
|             <div className="flex flex-col items-center gap-2"> |             <div className="flex flex-col items-center gap-2"> | ||||||
|               <div className="flex flex-col items-center justify-center gap-4"> |               <div className="flex flex-col items-center justify-center gap-4"> | ||||||
|                 {!loading ? ( |                 <Link | ||||||
|                   <Link |                   href={session ? "/api/auth/signout" : "/api/auth/signin"} | ||||||
|                     href={session ? "/api/auth/signout" : "/api/auth/signin"} |                   className="rounded-full bg-white/10 px-10 py-3 font-semibold no-underline transition hover:bg-white/20" | ||||||
|                     className="rounded-full bg-white/10 px-10 py-3 font-semibold no-underline transition hover:bg-white/20" |                 > | ||||||
|                   > |                   {session ? "Sign out" : "Sign in"} | ||||||
|                     {session ? "Sign out" : "Sign in"} |                 </Link> | ||||||
|                   </Link> |  | ||||||
|                 ) : ( |  | ||||||
|                   <div className="flex h-10 items-center justify-center"> |  | ||||||
|                     <svg |  | ||||||
|                       className="h-6 w-6 animate-spin text-white/70" |  | ||||||
|                       xmlns="http://www.w3.org/2000/svg" |  | ||||||
|                       fill="none" |  | ||||||
|                       viewBox="0 0 24 24" |  | ||||||
|                     > |  | ||||||
|                       <circle |  | ||||||
|                         className="opacity-25" |  | ||||||
|                         cx="12" |  | ||||||
|                         cy="12" |  | ||||||
|                         r="10" |  | ||||||
|                         stroke="currentColor" |  | ||||||
|                         strokeWidth="4" |  | ||||||
|                       /> |  | ||||||
|                       <path |  | ||||||
|                         className="opacity-75" |  | ||||||
|                         fill="currentColor" |  | ||||||
|                         d="M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z" |  | ||||||
|                       /> |  | ||||||
|                     </svg> |  | ||||||
|                   </div> |  | ||||||
|                 )} |  | ||||||
|               </div> |               </div> | ||||||
|             </div> |             </div> | ||||||
|           )} |           )} | ||||||
|         </div> |         </div> | ||||||
|       </main> |       </main> | ||||||
|     </> |     </HydrateClient> | ||||||
|   ); |   ); | ||||||
| } | } | ||||||
| 
 |  | ||||||
| export default Home; |  | ||||||
|  | |||||||
| @ -91,7 +91,7 @@ export default function SearchFile() { | |||||||
|                 className="flex place-content-end w-xxs flex-col gap-4 rounded-xl bg-white/10 p-4 hover:bg-white/20" |                 className="flex place-content-end w-xxs flex-col gap-4 rounded-xl bg-white/10 p-4 hover:bg-white/20" | ||||||
|               > |               > | ||||||
|                 <div className="self-center max-w-100 sm:max-w-50"> |                 <div className="self-center max-w-100 sm:max-w-50"> | ||||||
|                   <FilePreview fileId={file.id} fileType={file.extension} share={false} /> |                   <FilePreview fileId={file.id} fileType={file.extension} /> | ||||||
|                 </div> |                 </div> | ||||||
| 
 | 
 | ||||||
|                 <button onClick={() => router.push(pageUrl + file.url)}> |                 <button onClick={() => router.push(pageUrl + file.url)}> | ||||||
|  | |||||||
| @ -1,70 +0,0 @@ | |||||||
| import React, { Suspense } from "react"; |  | ||||||
| import { HomeButton } from "~/app/_components/HomeButton"; // Import the client component
 |  | ||||||
| import { Toaster } from "react-hot-toast"; |  | ||||||
| import { |  | ||||||
|   FileActionsContainer, |  | ||||||
| } from "~/app/_components/ActionButtons"; // Import the client component
 |  | ||||||
| 
 |  | ||||||
| const LoadingSkeleton: React.FC = () => ( |  | ||||||
|     <main className="flex min-h-screen flex-col items-center justify-center bg-gradient-to-b from-[#2e026d] to-[#15162c] text-white"> |  | ||||||
|       <div className="absolute top-4 left-4"> |  | ||||||
|          <HomeButton /> |  | ||||||
|       </div> |  | ||||||
|       <Toaster position="top-right" reverseOrder={false} /> |  | ||||||
|       <div className="container flex flex-col items-center gap-12 px-4 py-16"> |  | ||||||
|         <h1 className="text-5xl font-extrabold tracking-tight sm:text-[5rem]"> |  | ||||||
|           <span className="text-[hsl(280,100%,70%)]">File</span> Details |  | ||||||
|         </h1> |  | ||||||
|         <div className="mt-6"> |  | ||||||
|           <svg |  | ||||||
|                       className="h-6 w-6 animate-spin text-white/70" |  | ||||||
|                       xmlns="http://www.w3.org/2000/svg" |  | ||||||
|                       fill="none" |  | ||||||
|                       viewBox="0 0 24 24" |  | ||||||
|                     > |  | ||||||
|                       <circle |  | ||||||
|                         className="opacity-25" |  | ||||||
|                         cx="12" |  | ||||||
|                         cy="12" |  | ||||||
|                         r="10" |  | ||||||
|                         stroke="currentColor" |  | ||||||
|                         strokeWidth="4" |  | ||||||
|                       /> |  | ||||||
|                       <path |  | ||||||
|                         className="opacity-75" |  | ||||||
|                         fill="currentColor" |  | ||||||
|                         d="M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z" |  | ||||||
|                       /> |  | ||||||
|                     </svg> |  | ||||||
|         </div> |  | ||||||
|         <div className="w-full max-w-md rounded-lg bg-white/10 p-6 text-white shadow-md"> |  | ||||||
|           <p> |  | ||||||
|             <strong>Name:</strong> <span className="inline-block h-6 w-24 rounded bg-white/20 animate-pulse align-middle ml-2" /> |  | ||||||
|           </p> |  | ||||||
|           <p> |  | ||||||
|             <strong>Size:</strong> <span className="inline-block h-6 w-16 rounded bg-white/20 animate-pulse align-middle ml-2" /> |  | ||||||
|           </p> |  | ||||||
|           <p> |  | ||||||
|             <strong>Owner:</strong> <span className="inline-block h-6 w-20 rounded bg-white/20 animate-pulse align-middle ml-2" /> |  | ||||||
|           </p> |  | ||||||
|           <p> |  | ||||||
|             <strong>Upload Date:</strong> <span className="inline-block h-6 w-28 rounded bg-white/20 animate-pulse align-middle ml-2" /> |  | ||||||
|           </p> |  | ||||||
|           <div> |  | ||||||
|             <strong>Description:</strong> <span className="inline-block h-6 w-40 rounded bg-white/20 animate-pulse align-middle ml-2" /> |  | ||||||
|           </div> |  | ||||||
|           <div className="mt-4 flex justify-center"> |  | ||||||
|             <FileActionsContainer |  | ||||||
|               fileId={""} |  | ||||||
|               fileName={""} |  | ||||||
|               fileUrl={""} |  | ||||||
|               isOwner={false} |  | ||||||
|               isPublic={false} |  | ||||||
|             /> |  | ||||||
|           </div> |  | ||||||
|         </div> |  | ||||||
|       </div> |  | ||||||
|     </main> |  | ||||||
| ); |  | ||||||
| 
 |  | ||||||
| export default LoadingSkeleton; |  | ||||||
| @ -1,6 +0,0 @@ | |||||||
| import LoadingSkeleton from './LoadingSkeleton'; |  | ||||||
| 
 |  | ||||||
| export default function Loading() { |  | ||||||
|   // You can add any UI inside Loading, including a Skeleton.
 |  | ||||||
|   return <LoadingSkeleton /> |  | ||||||
| } |  | ||||||
| @ -1,5 +1,4 @@ | |||||||
| import { notFound } from "next/navigation"; | import { notFound } from "next/navigation"; | ||||||
| import { Suspense } from "react"; |  | ||||||
| import { FilePreview } from "~/app/_components/FilePreview"; | import { FilePreview } from "~/app/_components/FilePreview"; | ||||||
| import { HomeButton } from "~/app/_components/HomeButton"; // Import the client component
 | import { HomeButton } from "~/app/_components/HomeButton"; // Import the client component
 | ||||||
| import { Toaster } from "react-hot-toast"; | import { Toaster } from "react-hot-toast"; | ||||||
| @ -130,9 +129,7 @@ export default async function FilePreviewContainer({ | |||||||
|         </h1> |         </h1> | ||||||
|         <div className="mt-6"> |         <div className="mt-6"> | ||||||
|           {fileDetails.type !== "unknown" && ( |           {fileDetails.type !== "unknown" && ( | ||||||
|             <Suspense fallback={<div className="text-white">Loading...</div>}> |             <FilePreview fileId={fileDetails.id} fileType={fileDetails.type} /> | ||||||
|               <FilePreview fileId={fileDetails.id} fileType={fileDetails.type} share={true} /> |  | ||||||
|             </Suspense> |  | ||||||
|           )} |           )} | ||||||
|         </div> |         </div> | ||||||
|         <div className="w-full max-w-md rounded-lg bg-white/10 p-6 text-white shadow-md"> |         <div className="w-full max-w-md rounded-lg bg-white/10 p-6 text-white shadow-md"> | ||||||
| @ -151,40 +148,32 @@ export default async function FilePreviewContainer({ | |||||||
|           </p> |           </p> | ||||||
|           <p> |           <p> | ||||||
|             <strong>Owner:</strong>{" "} |             <strong>Owner:</strong>{" "} | ||||||
|             <Suspense fallback={<div className="text-white">Loading...</div>}> |             <img | ||||||
|               <img |  | ||||||
|               className="inline size-5 rounded-md" |               className="inline size-5 rounded-md" | ||||||
|               src={fileDetails.ownerAvatar || ""} |               src={fileDetails.ownerAvatar || ""} | ||||||
|               alt="Owner avatar" |               alt="Owner avatar" | ||||||
|               />{" "} |             />{" "} | ||||||
|             {fileDetails.owner} |             {fileDetails.owner} | ||||||
|             </Suspense> |  | ||||||
|           </p> |           </p> | ||||||
|           <p> |           <p> | ||||||
|             <strong>Upload Date:</strong>{" "} |             <strong>Upload Date:</strong>{" "} | ||||||
|             <Suspense fallback={<div className="text-white">Loading...</div>}> |             {new Date(fileDetails.uploadDate).toLocaleString()} | ||||||
|               {new Date(fileDetails.uploadDate).toLocaleString()} |  | ||||||
|             </Suspense> |  | ||||||
|           </p> |           </p> | ||||||
|           <div> |           <div> | ||||||
|             <strong>Description:</strong>{" "} |             <strong>Description:</strong>{" "} | ||||||
|             <Suspense fallback={<div className="text-white">Loading...</div>}> |             <FileDescriptionContainer | ||||||
|               <FileDescriptionContainer |               fileId={fileDetails.id} | ||||||
|                 fileId={fileDetails.id} |               fileDescription={fileDetails.description} | ||||||
|                 fileDescription={fileDetails.description} |             /> | ||||||
|               /> |  | ||||||
|             </Suspense> |  | ||||||
|           </div> |           </div> | ||||||
|           <div className="mt-4 flex justify-center"> |           <div className="mt-4 flex justify-center"> | ||||||
|             <Suspense fallback={<div className="text-white">Loading...</div>}> |             <FileActionsContainer | ||||||
|               <FileActionsContainer |               fileId={fileDetails.id} | ||||||
|                 fileId={fileDetails.id} |               fileName={fileDetails.name} | ||||||
|                 fileName={fileDetails.name} |               fileUrl={fileDetails.url} | ||||||
|                 fileUrl={fileDetails.url} |               isOwner={session?.user?.id ? await checkOwner(fileDetails.ownerId, session.user.id) : false} | ||||||
|                 isOwner={session?.user?.id ? await checkOwner(fileDetails.ownerId, session.user.id) : false} |               isPublic={fileDetails.isPublic} | ||||||
|                 isPublic={fileDetails.isPublic} |             /> | ||||||
|               /> |  | ||||||
|             </Suspense> |  | ||||||
|           </div> |           </div> | ||||||
|         </div> |         </div> | ||||||
|       </div> |       </div> | ||||||
|  | |||||||
| @ -1,9 +0,0 @@ | |||||||
| .markdown-body ul, |  | ||||||
| .markdown-body ol { |  | ||||||
|   list-style: initial; /* Ensures bullets or numbers are displayed */ |  | ||||||
|   margin-left: 1.5em; /* Adds proper indentation */ |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .markdown-body li { |  | ||||||
|   margin-bottom: 0.5em; /* Adds spacing between list items */ |  | ||||||
| } |  | ||||||
| @ -1,78 +0,0 @@ | |||||||
| import { useEffect } from "react"; |  | ||||||
| import "github-markdown-css/github-markdown.css"; |  | ||||||
| 
 |  | ||||||
| interface MarkdownRendererProps { |  | ||||||
|   markdownContent: string; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export function MarkdownRenderer({ markdownContent }: MarkdownRendererProps) { |  | ||||||
|   useEffect(() => { |  | ||||||
|     if (markdownContent) { |  | ||||||
|       const markdownContainer = document.querySelector("#markdown-preview"); |  | ||||||
|       if (!markdownContainer) return; |  | ||||||
| 
 |  | ||||||
|       const codeBlocks = markdownContainer.querySelectorAll("code"); |  | ||||||
| 
 |  | ||||||
|       codeBlocks.forEach((block) => { |  | ||||||
|         // Check if the block is already wrapped
 |  | ||||||
|         if (block.parentElement?.classList.contains("code-wrapper")) return; |  | ||||||
| 
 |  | ||||||
|         // Check if the code block is multiline
 |  | ||||||
|         const isMultiline = block.textContent?.includes("\n"); |  | ||||||
|         if (!isMultiline) return; |  | ||||||
| 
 |  | ||||||
|         // Create a wrapper only if it doesn't already exist
 |  | ||||||
|         const wrapper = document.createElement("div"); |  | ||||||
|         wrapper.className = "code-wrapper"; // Add a class to identify the wrapper
 |  | ||||||
|         wrapper.style.display = "flex"; |  | ||||||
|         wrapper.style.alignItems = "flex-start"; |  | ||||||
|         wrapper.style.justifyContent = "space-between"; |  | ||||||
|         wrapper.style.gap = "8px"; |  | ||||||
|         wrapper.style.width = "100%"; |  | ||||||
|         wrapper.style.position = "relative"; |  | ||||||
| 
 |  | ||||||
|         const codeContainer = document.createElement("div"); |  | ||||||
|         codeContainer.style.flex = "1"; |  | ||||||
|         codeContainer.appendChild(block.cloneNode(true)); |  | ||||||
| 
 |  | ||||||
|         const button = document.createElement("button"); |  | ||||||
|         button.innerHTML = ` |  | ||||||
|           <img src="/icons/copy.svg" alt="Copy" class="h-4 w-4" style="filter: invert(1) sepia(1) saturate(5) hue-rotate(180deg);"/> |  | ||||||
|         `;
 |  | ||||||
|         button.className = |  | ||||||
|           "copy-button inline-flex items-center justify-center bg-gray-200 rounded hover:bg-gray-300 dark:bg-gray-700 dark:text-gray-200 dark:hover:bg-gray-600 transition"; |  | ||||||
|         button.style.marginLeft = "8px"; |  | ||||||
|         button.style.width = "1.5rem"; |  | ||||||
|         button.style.height = "1.5rem"; |  | ||||||
| 
 |  | ||||||
|         button.addEventListener("click", () => { |  | ||||||
|           navigator.clipboard.writeText(block.textContent || "").then(() => { |  | ||||||
|             button.innerHTML = ` |  | ||||||
|               <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"> |  | ||||||
|                 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" /> |  | ||||||
|               </svg> |  | ||||||
|             `;
 |  | ||||||
|             setTimeout(() => { |  | ||||||
|               button.innerHTML = ` |  | ||||||
|                 <img src="/icons/copy.svg" alt="Copy" class="h-4 w-4" style="filter: invert(1) sepia(1) saturate(5) hue-rotate(180deg);"/> |  | ||||||
|               `;
 |  | ||||||
|             }, 2000); |  | ||||||
|           }); |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|         wrapper.appendChild(codeContainer); |  | ||||||
|         wrapper.appendChild(button); |  | ||||||
| 
 |  | ||||||
|         // Replace the original block with the wrapper
 |  | ||||||
|         block.replaceWith(wrapper); |  | ||||||
|       }); |  | ||||||
|     } |  | ||||||
|   }, [markdownContent]); |  | ||||||
| 
 |  | ||||||
|   return ( |  | ||||||
|     <div className="markdown-body max-w-full p-4 pt-0 pb-0" id="markdown-preview"> |  | ||||||
|       <div dangerouslySetInnerHTML={{ __html: markdownContent }} /> |  | ||||||
|     </div> |  | ||||||
|   ); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| @ -1,5 +1,4 @@ | |||||||
| import { PrismaClient } from "~/app/generated/prisma-client"; | import { PrismaClient } from "@prisma/client"; | ||||||
| import { withAccelerate } from '@prisma/extension-accelerate' |  | ||||||
| 
 | 
 | ||||||
| import { env } from "~/env"; | import { env } from "~/env"; | ||||||
| 
 | 
 | ||||||
| @ -7,7 +6,7 @@ const createPrismaClient = () => | |||||||
|   new PrismaClient({ |   new PrismaClient({ | ||||||
|     log: |     log: | ||||||
|       env.NODE_ENV === "development" ? ["query", "error", "warn"] : ["error"], |       env.NODE_ENV === "development" ? ["query", "error", "warn"] : ["error"], | ||||||
|   }).$extends(withAccelerate()); |   }); | ||||||
| 
 | 
 | ||||||
| const globalForPrisma = globalThis as unknown as { | const globalForPrisma = globalThis as unknown as { | ||||||
|   prisma: ReturnType<typeof createPrismaClient> | undefined; |   prisma: ReturnType<typeof createPrismaClient> | undefined; | ||||||
|  | |||||||
| @ -1,48 +1,32 @@ | |||||||
| // This function takes a file name as input and returns the file type based on its extension.
 | // This function takes a file name as input and returns the file type based on its extension.
 | ||||||
| import mime from "mime-types"; |  | ||||||
| 
 | 
 | ||||||
| export function getFileType(fileName: string): string { | export function getFileType(fileName: string): string { | ||||||
|     const extension = fileName.split(".").pop()?.toLowerCase(); |     const extension = fileName.split(".").pop()?.toLowerCase(); | ||||||
|     const fileTypes: Record<string, string> = { |     const fileTypes: Record<string, string> = { | ||||||
|         // Video
 |  | ||||||
|         "mp4": "video/mp4", |         "mp4": "video/mp4", | ||||||
|         "webm": "video/webm", |         "webm": "video/webm", | ||||||
|         "ogg": "video/ogg", |         "ogg": "video/ogg", | ||||||
|         // Image
 |  | ||||||
|         "jpg": "image/jpeg", |         "jpg": "image/jpeg", | ||||||
|         "jpeg": "image/jpeg", |         "jpeg": "image/jpeg", | ||||||
|         "png": "image/png", |         "png": "image/png", | ||||||
|         "gif": "image/gif", |         "gif": "image/gif", | ||||||
|         "svg": "image/svg+xml", |         "svg": "image/svg+xml", | ||||||
|         // Audio
 |  | ||||||
|         "mp3": "audio/mpeg", |         "mp3": "audio/mpeg", | ||||||
|         "wav": "audio/wav", |         "wav": "audio/wav", | ||||||
|         // Archive
 |  | ||||||
|         "zip": "archive/zip", |         "zip": "archive/zip", | ||||||
|         "rar": "archive/rar", |         "rar": "archive/rar", | ||||||
|         "jar": "archive/jar", |  | ||||||
|         "iso": "archive/iso", |  | ||||||
|         // Text
 |  | ||||||
|         "pdf": "text/pdf", |         "pdf": "text/pdf", | ||||||
|         "txt": "text/plain", |         "txt": "text/plain", | ||||||
|         // Code
 |  | ||||||
|         "c": "code/c", |         "c": "code/c", | ||||||
|         "cpp": "code/cpp", |         "cpp": "code/cpp", | ||||||
|         "py": "code/python", |         "py": "code/python", | ||||||
|         "js": "code/javascript", |         "js": "code/javascript", | ||||||
|         "html": "code/html", |         "html": "code/html", | ||||||
|         "css": "code/css", |         "css": "code/css", | ||||||
|  |         "md": "markdown/markdown", | ||||||
|         "json": "code/json", |         "json": "code/json", | ||||||
|         "xml": "code/xml", |         "xml": "code/xml", | ||||||
|         "csv": "code/csv", |         "csv": "code/csv", | ||||||
|         // Markdown
 |  | ||||||
|         "md": "markdown/markdown", |  | ||||||
|         // Applications
 |  | ||||||
|         "exe": "application/executable", |  | ||||||
|         "apk": "application/android", |  | ||||||
|     }; |     }; | ||||||
|     return extension ? fileTypes[extension] || |     return extension ? fileTypes[extension] || "unknown" : "unknown"; | ||||||
|     //get the file type using the mime type library
 |  | ||||||
|     mime.lookup(extension) || "application/octet-stream" : "application/octet-stream"; |  | ||||||
| 
 |  | ||||||
|   }; |   }; | ||||||
| @ -34,8 +34,8 @@ | |||||||
|     "next-env.d.ts", |     "next-env.d.ts", | ||||||
|     "**/*.ts", |     "**/*.ts", | ||||||
|     "**/*.tsx", |     "**/*.tsx", | ||||||
|     // "**/*.cjs", |     "**/*.cjs", | ||||||
|     // "**/*.js", |     "**/*.js", | ||||||
|     ".next/types/**/*.ts" |     ".next/types/**/*.ts" | ||||||
|   ], |   ], | ||||||
|   "exclude": ["node_modules"] |   "exclude": ["node_modules"] | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user