mirror of
https://github.com/diced/zipline.git
synced 2025-12-12 15:50:11 -08:00
fix: a bunch of small fixes
This commit is contained in:
@@ -17,7 +17,7 @@
|
||||
"validate": "pnpm run \"/^validate:.*/\"",
|
||||
"validate:lint": "eslint --cache --ignore-path .gitignore --fix .",
|
||||
"validate:format": "prettier --write --ignore-path .gitignore .",
|
||||
"db:prototype": "prisma db push && prisma generate"
|
||||
"db:prototype": "prisma db push --skip-generate && prisma generate --no-hints"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/plots": "^1.2.6",
|
||||
|
||||
315
pnpm-lock.yaml
generated
315
pnpm-lock.yaml
generated
@@ -256,8 +256,8 @@ packages:
|
||||
resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
'@ampproject/remapping@2.2.1':
|
||||
resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==}
|
||||
'@ampproject/remapping@2.3.0':
|
||||
resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
|
||||
'@ant-design/plots@1.2.6':
|
||||
@@ -494,24 +494,28 @@ packages:
|
||||
resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/compat-data@7.23.5':
|
||||
resolution: {integrity: sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==}
|
||||
'@babel/code-frame@7.24.7':
|
||||
resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/compat-data@7.25.4':
|
||||
resolution: {integrity: sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/core@7.23.5':
|
||||
resolution: {integrity: sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/generator@7.23.5':
|
||||
resolution: {integrity: sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==}
|
||||
'@babel/generator@7.25.6':
|
||||
resolution: {integrity: sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-annotate-as-pure@7.22.5':
|
||||
resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-compilation-targets@7.22.15':
|
||||
resolution: {integrity: sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==}
|
||||
'@babel/helper-compilation-targets@7.25.2':
|
||||
resolution: {integrity: sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-create-class-features-plugin@7.23.5':
|
||||
@@ -528,20 +532,16 @@ packages:
|
||||
resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-hoist-variables@7.22.5':
|
||||
resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-member-expression-to-functions@7.23.0':
|
||||
resolution: {integrity: sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-module-imports@7.22.15':
|
||||
resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==}
|
||||
'@babel/helper-module-imports@7.24.7':
|
||||
resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-module-transforms@7.23.3':
|
||||
resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==}
|
||||
'@babel/helper-module-transforms@7.25.2':
|
||||
resolution: {integrity: sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0
|
||||
@@ -560,8 +560,8 @@ packages:
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0
|
||||
|
||||
'@babel/helper-simple-access@7.22.5':
|
||||
resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==}
|
||||
'@babel/helper-simple-access@7.24.7':
|
||||
resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-skip-transparent-expression-wrappers@7.22.5':
|
||||
@@ -576,27 +576,44 @@ packages:
|
||||
resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-string-parser@7.24.8':
|
||||
resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-validator-identifier@7.22.20':
|
||||
resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-validator-option@7.23.5':
|
||||
resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==}
|
||||
'@babel/helper-validator-identifier@7.24.7':
|
||||
resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helpers@7.23.5':
|
||||
resolution: {integrity: sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg==}
|
||||
'@babel/helper-validator-option@7.24.8':
|
||||
resolution: {integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helpers@7.25.6':
|
||||
resolution: {integrity: sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/highlight@7.23.4':
|
||||
resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/highlight@7.24.7':
|
||||
resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/parser@7.23.5':
|
||||
resolution: {integrity: sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
hasBin: true
|
||||
|
||||
'@babel/parser@7.25.6':
|
||||
resolution: {integrity: sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
hasBin: true
|
||||
|
||||
'@babel/plugin-proposal-class-properties@7.18.6':
|
||||
resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
@@ -612,14 +629,22 @@ packages:
|
||||
resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/traverse@7.23.5':
|
||||
resolution: {integrity: sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w==}
|
||||
'@babel/template@7.25.0':
|
||||
resolution: {integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/traverse@7.25.6':
|
||||
resolution: {integrity: sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/types@7.23.5':
|
||||
resolution: {integrity: sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/types@7.25.6':
|
||||
resolution: {integrity: sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@esbuild/aix-ppc64@0.19.12':
|
||||
resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -996,20 +1021,38 @@ packages:
|
||||
resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
|
||||
'@jridgewell/gen-mapping@0.3.5':
|
||||
resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
|
||||
'@jridgewell/resolve-uri@3.1.1':
|
||||
resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
|
||||
'@jridgewell/resolve-uri@3.1.2':
|
||||
resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
|
||||
'@jridgewell/set-array@1.1.2':
|
||||
resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
|
||||
'@jridgewell/set-array@1.2.1':
|
||||
resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
|
||||
'@jridgewell/sourcemap-codec@1.4.15':
|
||||
resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
|
||||
|
||||
'@jridgewell/sourcemap-codec@1.5.0':
|
||||
resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
|
||||
|
||||
'@jridgewell/trace-mapping@0.3.20':
|
||||
resolution: {integrity: sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==}
|
||||
|
||||
'@jridgewell/trace-mapping@0.3.25':
|
||||
resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
|
||||
|
||||
'@ljharb/resumer@0.0.1':
|
||||
resolution: {integrity: sha512-skQiAOrCfO7vRTq53cxznMpks7wS1va95UCidALlOVWqvBAzwPVErwizDwoMqNVMEn1mDq0utxZd02eIrvF1lw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -1848,8 +1891,8 @@ packages:
|
||||
resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
browserslist@4.22.1:
|
||||
resolution: {integrity: sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==}
|
||||
browserslist@4.23.3:
|
||||
resolution: {integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==}
|
||||
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
|
||||
hasBin: true
|
||||
|
||||
@@ -1903,8 +1946,8 @@ packages:
|
||||
resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
caniuse-lite@1.0.30001565:
|
||||
resolution: {integrity: sha512-xrE//a3O7TP0vaJ8ikzkD2c2NgcVUvsEe2IvFTntV4Yd1Z9FVzh+gW+enX96L0psrbaFMcVcH2l90xNuGDWc8w==}
|
||||
caniuse-lite@1.0.30001660:
|
||||
resolution: {integrity: sha512-GacvNTTuATm26qC74pt+ad1fW15mlQ/zuTzzY1ZoIzECTP8HURDfF43kNxPgf7H1jmelCBQTTbBNxdSXOA7Bqg==}
|
||||
|
||||
ccount@2.0.1:
|
||||
resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
|
||||
@@ -2111,6 +2154,15 @@ packages:
|
||||
supports-color:
|
||||
optional: true
|
||||
|
||||
debug@4.3.7:
|
||||
resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==}
|
||||
engines: {node: '>=6.0'}
|
||||
peerDependencies:
|
||||
supports-color: '*'
|
||||
peerDependenciesMeta:
|
||||
supports-color:
|
||||
optional: true
|
||||
|
||||
decamelize@1.2.0:
|
||||
resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -2231,8 +2283,8 @@ packages:
|
||||
ee-first@1.1.1:
|
||||
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
|
||||
|
||||
electron-to-chromium@1.4.600:
|
||||
resolution: {integrity: sha512-KD6CWjf1BnQG+NsXuyiTDDT1eV13sKuYsOUioXkQweYTQIbgHkXPry9K7M+7cKtYHnSUPitVaLrXYB1jTkkYrw==}
|
||||
electron-to-chromium@1.5.21:
|
||||
resolution: {integrity: sha512-+rBAerCpQvFSPyAO677i5gJuWGO2WFsoujENdcMzsrpP7Ebcc3pmpERgU8CV4fFF10a5haP4ivnFQ/AmLICBVg==}
|
||||
|
||||
emoji-regex@8.0.0:
|
||||
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
|
||||
@@ -2286,8 +2338,8 @@ packages:
|
||||
engines: {node: '>=12'}
|
||||
hasBin: true
|
||||
|
||||
escalade@3.1.1:
|
||||
resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
|
||||
escalade@3.2.0:
|
||||
resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
escape-html@1.0.3:
|
||||
@@ -3453,8 +3505,8 @@ packages:
|
||||
encoding:
|
||||
optional: true
|
||||
|
||||
node-releases@2.0.14:
|
||||
resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==}
|
||||
node-releases@2.0.18:
|
||||
resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==}
|
||||
|
||||
nopt@5.0.0:
|
||||
resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==}
|
||||
@@ -3622,6 +3674,9 @@ packages:
|
||||
picocolors@1.0.0:
|
||||
resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
|
||||
|
||||
picocolors@1.1.0:
|
||||
resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==}
|
||||
|
||||
picomatch@2.3.1:
|
||||
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
|
||||
engines: {node: '>=8.6'}
|
||||
@@ -4482,8 +4537,8 @@ packages:
|
||||
resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
update-browserslist-db@1.0.13:
|
||||
resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==}
|
||||
update-browserslist-db@1.1.0:
|
||||
resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
browserslist: '>= 4.21.0'
|
||||
@@ -4737,10 +4792,10 @@ snapshots:
|
||||
|
||||
'@aashutoshrathi/word-wrap@1.2.6': {}
|
||||
|
||||
'@ampproject/remapping@2.2.1':
|
||||
'@ampproject/remapping@2.3.0':
|
||||
dependencies:
|
||||
'@jridgewell/gen-mapping': 0.3.3
|
||||
'@jridgewell/trace-mapping': 0.3.20
|
||||
'@jridgewell/gen-mapping': 0.3.5
|
||||
'@jridgewell/trace-mapping': 0.3.25
|
||||
|
||||
'@ant-design/plots@1.2.6(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
|
||||
dependencies:
|
||||
@@ -5397,44 +5452,49 @@ snapshots:
|
||||
'@babel/highlight': 7.23.4
|
||||
chalk: 2.4.2
|
||||
|
||||
'@babel/compat-data@7.23.5': {}
|
||||
'@babel/code-frame@7.24.7':
|
||||
dependencies:
|
||||
'@babel/highlight': 7.24.7
|
||||
picocolors: 1.1.0
|
||||
|
||||
'@babel/compat-data@7.25.4': {}
|
||||
|
||||
'@babel/core@7.23.5':
|
||||
dependencies:
|
||||
'@ampproject/remapping': 2.2.1
|
||||
'@babel/code-frame': 7.23.5
|
||||
'@babel/generator': 7.23.5
|
||||
'@babel/helper-compilation-targets': 7.22.15
|
||||
'@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.5)
|
||||
'@babel/helpers': 7.23.5
|
||||
'@babel/parser': 7.23.5
|
||||
'@babel/template': 7.22.15
|
||||
'@babel/traverse': 7.23.5
|
||||
'@babel/types': 7.23.5
|
||||
'@ampproject/remapping': 2.3.0
|
||||
'@babel/code-frame': 7.24.7
|
||||
'@babel/generator': 7.25.6
|
||||
'@babel/helper-compilation-targets': 7.25.2
|
||||
'@babel/helper-module-transforms': 7.25.2(@babel/core@7.23.5)
|
||||
'@babel/helpers': 7.25.6
|
||||
'@babel/parser': 7.25.6
|
||||
'@babel/template': 7.25.0
|
||||
'@babel/traverse': 7.25.6
|
||||
'@babel/types': 7.25.6
|
||||
convert-source-map: 2.0.0
|
||||
debug: 4.3.4
|
||||
debug: 4.3.7
|
||||
gensync: 1.0.0-beta.2
|
||||
json5: 2.2.3
|
||||
semver: 6.3.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/generator@7.23.5':
|
||||
'@babel/generator@7.25.6':
|
||||
dependencies:
|
||||
'@babel/types': 7.23.5
|
||||
'@jridgewell/gen-mapping': 0.3.3
|
||||
'@jridgewell/trace-mapping': 0.3.20
|
||||
'@babel/types': 7.25.6
|
||||
'@jridgewell/gen-mapping': 0.3.5
|
||||
'@jridgewell/trace-mapping': 0.3.25
|
||||
jsesc: 2.5.2
|
||||
|
||||
'@babel/helper-annotate-as-pure@7.22.5':
|
||||
dependencies:
|
||||
'@babel/types': 7.23.5
|
||||
|
||||
'@babel/helper-compilation-targets@7.22.15':
|
||||
'@babel/helper-compilation-targets@7.25.2':
|
||||
dependencies:
|
||||
'@babel/compat-data': 7.23.5
|
||||
'@babel/helper-validator-option': 7.23.5
|
||||
browserslist: 4.22.1
|
||||
'@babel/compat-data': 7.25.4
|
||||
'@babel/helper-validator-option': 7.24.8
|
||||
browserslist: 4.23.3
|
||||
lru-cache: 5.1.1
|
||||
semver: 6.3.1
|
||||
|
||||
@@ -5458,26 +5518,26 @@ snapshots:
|
||||
'@babel/template': 7.22.15
|
||||
'@babel/types': 7.23.5
|
||||
|
||||
'@babel/helper-hoist-variables@7.22.5':
|
||||
dependencies:
|
||||
'@babel/types': 7.23.5
|
||||
|
||||
'@babel/helper-member-expression-to-functions@7.23.0':
|
||||
dependencies:
|
||||
'@babel/types': 7.23.5
|
||||
|
||||
'@babel/helper-module-imports@7.22.15':
|
||||
'@babel/helper-module-imports@7.24.7':
|
||||
dependencies:
|
||||
'@babel/types': 7.23.5
|
||||
'@babel/traverse': 7.25.6
|
||||
'@babel/types': 7.25.6
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/helper-module-transforms@7.23.3(@babel/core@7.23.5)':
|
||||
'@babel/helper-module-transforms@7.25.2(@babel/core@7.23.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.23.5
|
||||
'@babel/helper-environment-visitor': 7.22.20
|
||||
'@babel/helper-module-imports': 7.22.15
|
||||
'@babel/helper-simple-access': 7.22.5
|
||||
'@babel/helper-split-export-declaration': 7.22.6
|
||||
'@babel/helper-validator-identifier': 7.22.20
|
||||
'@babel/helper-module-imports': 7.24.7
|
||||
'@babel/helper-simple-access': 7.24.7
|
||||
'@babel/helper-validator-identifier': 7.24.7
|
||||
'@babel/traverse': 7.25.6
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/helper-optimise-call-expression@7.22.5':
|
||||
dependencies:
|
||||
@@ -5492,9 +5552,12 @@ snapshots:
|
||||
'@babel/helper-member-expression-to-functions': 7.23.0
|
||||
'@babel/helper-optimise-call-expression': 7.22.5
|
||||
|
||||
'@babel/helper-simple-access@7.22.5':
|
||||
'@babel/helper-simple-access@7.24.7':
|
||||
dependencies:
|
||||
'@babel/types': 7.23.5
|
||||
'@babel/traverse': 7.25.6
|
||||
'@babel/types': 7.25.6
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/helper-skip-transparent-expression-wrappers@7.22.5':
|
||||
dependencies:
|
||||
@@ -5506,17 +5569,18 @@ snapshots:
|
||||
|
||||
'@babel/helper-string-parser@7.23.4': {}
|
||||
|
||||
'@babel/helper-string-parser@7.24.8': {}
|
||||
|
||||
'@babel/helper-validator-identifier@7.22.20': {}
|
||||
|
||||
'@babel/helper-validator-option@7.23.5': {}
|
||||
'@babel/helper-validator-identifier@7.24.7': {}
|
||||
|
||||
'@babel/helpers@7.23.5':
|
||||
'@babel/helper-validator-option@7.24.8': {}
|
||||
|
||||
'@babel/helpers@7.25.6':
|
||||
dependencies:
|
||||
'@babel/template': 7.22.15
|
||||
'@babel/traverse': 7.23.5
|
||||
'@babel/types': 7.23.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
'@babel/template': 7.25.0
|
||||
'@babel/types': 7.25.6
|
||||
|
||||
'@babel/highlight@7.23.4':
|
||||
dependencies:
|
||||
@@ -5524,10 +5588,21 @@ snapshots:
|
||||
chalk: 2.4.2
|
||||
js-tokens: 4.0.0
|
||||
|
||||
'@babel/highlight@7.24.7':
|
||||
dependencies:
|
||||
'@babel/helper-validator-identifier': 7.24.7
|
||||
chalk: 2.4.2
|
||||
js-tokens: 4.0.0
|
||||
picocolors: 1.1.0
|
||||
|
||||
'@babel/parser@7.23.5':
|
||||
dependencies:
|
||||
'@babel/types': 7.23.5
|
||||
|
||||
'@babel/parser@7.25.6':
|
||||
dependencies:
|
||||
'@babel/types': 7.25.6
|
||||
|
||||
'@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.23.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.23.5
|
||||
@@ -5544,17 +5619,20 @@ snapshots:
|
||||
'@babel/parser': 7.23.5
|
||||
'@babel/types': 7.23.5
|
||||
|
||||
'@babel/traverse@7.23.5':
|
||||
'@babel/template@7.25.0':
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.23.5
|
||||
'@babel/generator': 7.23.5
|
||||
'@babel/helper-environment-visitor': 7.22.20
|
||||
'@babel/helper-function-name': 7.23.0
|
||||
'@babel/helper-hoist-variables': 7.22.5
|
||||
'@babel/helper-split-export-declaration': 7.22.6
|
||||
'@babel/parser': 7.23.5
|
||||
'@babel/types': 7.23.5
|
||||
debug: 4.3.4
|
||||
'@babel/code-frame': 7.24.7
|
||||
'@babel/parser': 7.25.6
|
||||
'@babel/types': 7.25.6
|
||||
|
||||
'@babel/traverse@7.25.6':
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.24.7
|
||||
'@babel/generator': 7.25.6
|
||||
'@babel/parser': 7.25.6
|
||||
'@babel/template': 7.25.0
|
||||
'@babel/types': 7.25.6
|
||||
debug: 4.3.7
|
||||
globals: 11.12.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@@ -5565,6 +5643,12 @@ snapshots:
|
||||
'@babel/helper-validator-identifier': 7.22.20
|
||||
to-fast-properties: 2.0.0
|
||||
|
||||
'@babel/types@7.25.6':
|
||||
dependencies:
|
||||
'@babel/helper-string-parser': 7.24.8
|
||||
'@babel/helper-validator-identifier': 7.24.7
|
||||
to-fast-properties: 2.0.0
|
||||
|
||||
'@esbuild/aix-ppc64@0.19.12':
|
||||
optional: true
|
||||
|
||||
@@ -5851,17 +5935,34 @@ snapshots:
|
||||
'@jridgewell/sourcemap-codec': 1.4.15
|
||||
'@jridgewell/trace-mapping': 0.3.20
|
||||
|
||||
'@jridgewell/gen-mapping@0.3.5':
|
||||
dependencies:
|
||||
'@jridgewell/set-array': 1.2.1
|
||||
'@jridgewell/sourcemap-codec': 1.5.0
|
||||
'@jridgewell/trace-mapping': 0.3.25
|
||||
|
||||
'@jridgewell/resolve-uri@3.1.1': {}
|
||||
|
||||
'@jridgewell/resolve-uri@3.1.2': {}
|
||||
|
||||
'@jridgewell/set-array@1.1.2': {}
|
||||
|
||||
'@jridgewell/set-array@1.2.1': {}
|
||||
|
||||
'@jridgewell/sourcemap-codec@1.4.15': {}
|
||||
|
||||
'@jridgewell/sourcemap-codec@1.5.0': {}
|
||||
|
||||
'@jridgewell/trace-mapping@0.3.20':
|
||||
dependencies:
|
||||
'@jridgewell/resolve-uri': 3.1.1
|
||||
'@jridgewell/sourcemap-codec': 1.4.15
|
||||
|
||||
'@jridgewell/trace-mapping@0.3.25':
|
||||
dependencies:
|
||||
'@jridgewell/resolve-uri': 3.1.2
|
||||
'@jridgewell/sourcemap-codec': 1.5.0
|
||||
|
||||
'@ljharb/resumer@0.0.1':
|
||||
dependencies:
|
||||
'@ljharb/through': 2.3.11
|
||||
@@ -6906,12 +7007,12 @@ snapshots:
|
||||
dependencies:
|
||||
fill-range: 7.0.1
|
||||
|
||||
browserslist@4.22.1:
|
||||
browserslist@4.23.3:
|
||||
dependencies:
|
||||
caniuse-lite: 1.0.30001565
|
||||
electron-to-chromium: 1.4.600
|
||||
node-releases: 2.0.14
|
||||
update-browserslist-db: 1.0.13(browserslist@4.22.1)
|
||||
caniuse-lite: 1.0.30001660
|
||||
electron-to-chromium: 1.5.21
|
||||
node-releases: 2.0.18
|
||||
update-browserslist-db: 1.1.0(browserslist@4.23.3)
|
||||
|
||||
buffer-from@1.1.2: {}
|
||||
|
||||
@@ -6956,7 +7057,7 @@ snapshots:
|
||||
|
||||
camelcase@5.3.1: {}
|
||||
|
||||
caniuse-lite@1.0.30001565: {}
|
||||
caniuse-lite@1.0.30001660: {}
|
||||
|
||||
ccount@2.0.1: {}
|
||||
|
||||
@@ -7136,6 +7237,10 @@ snapshots:
|
||||
dependencies:
|
||||
ms: 2.1.2
|
||||
|
||||
debug@4.3.7:
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
|
||||
decamelize@1.2.0: {}
|
||||
|
||||
decimal.js@10.4.3: {}
|
||||
@@ -7242,7 +7347,7 @@ snapshots:
|
||||
|
||||
ee-first@1.1.1: {}
|
||||
|
||||
electron-to-chromium@1.4.600: {}
|
||||
electron-to-chromium@1.5.21: {}
|
||||
|
||||
emoji-regex@8.0.0: {}
|
||||
|
||||
@@ -7389,7 +7494,7 @@ snapshots:
|
||||
'@esbuild/win32-ia32': 0.19.12
|
||||
'@esbuild/win32-x64': 0.19.12
|
||||
|
||||
escalade@3.1.1: {}
|
||||
escalade@3.2.0: {}
|
||||
|
||||
escape-html@1.0.3: {}
|
||||
|
||||
@@ -8829,7 +8934,7 @@ snapshots:
|
||||
'@next/env': 14.0.3
|
||||
'@swc/helpers': 0.5.2
|
||||
busboy: 1.6.0
|
||||
caniuse-lite: 1.0.30001565
|
||||
caniuse-lite: 1.0.30001660
|
||||
postcss: 8.4.31
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
@@ -8862,7 +8967,7 @@ snapshots:
|
||||
dependencies:
|
||||
whatwg-url: 5.0.0
|
||||
|
||||
node-releases@2.0.14: {}
|
||||
node-releases@2.0.18: {}
|
||||
|
||||
nopt@5.0.0:
|
||||
dependencies:
|
||||
@@ -9032,6 +9137,8 @@ snapshots:
|
||||
|
||||
picocolors@1.0.0: {}
|
||||
|
||||
picocolors@1.1.0: {}
|
||||
|
||||
picomatch@2.3.1: {}
|
||||
|
||||
pino-abstract-transport@1.1.0:
|
||||
@@ -9999,11 +10106,11 @@ snapshots:
|
||||
|
||||
untildify@4.0.0: {}
|
||||
|
||||
update-browserslist-db@1.0.13(browserslist@4.22.1):
|
||||
update-browserslist-db@1.1.0(browserslist@4.23.3):
|
||||
dependencies:
|
||||
browserslist: 4.22.1
|
||||
escalade: 3.1.1
|
||||
picocolors: 1.0.0
|
||||
browserslist: 4.23.3
|
||||
escalade: 3.2.0
|
||||
picocolors: 1.1.0
|
||||
|
||||
uri-js@4.4.1:
|
||||
dependencies:
|
||||
|
||||
@@ -64,6 +64,7 @@ model Zipline {
|
||||
websiteExternalLinks Json @default("[{ \"name\": \"GitHub\", \"url\": \"https://github.com/diced/zipline\"}, { \"name\": \"Documentation\", \"url\": \"https://zipline.diced.sh/\"}]")
|
||||
websiteLoginBackground String?
|
||||
websiteDefaultAvatar String?
|
||||
websiteTos String?
|
||||
|
||||
websiteThemeDefault String @default("system")
|
||||
websiteThemeDark String @default("builtin:dark_gray")
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
Menu,
|
||||
NavLink,
|
||||
Paper,
|
||||
ScrollArea,
|
||||
Title,
|
||||
useMantineColorScheme,
|
||||
useMantineTheme,
|
||||
@@ -30,6 +31,7 @@ import {
|
||||
IconFileUpload,
|
||||
IconFiles,
|
||||
IconFolder,
|
||||
IconGraph,
|
||||
IconHome,
|
||||
IconLink,
|
||||
IconLogout,
|
||||
@@ -45,7 +47,6 @@ import Link from 'next/link';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useState } from 'react';
|
||||
import ConfigProvider from './ConfigProvider';
|
||||
import { IconGraph } from '@tabler/icons-react';
|
||||
|
||||
type NavLinks = {
|
||||
label: string;
|
||||
@@ -355,19 +356,21 @@ export default function Layout({ children, config }: { children: React.ReactNode
|
||||
}
|
||||
})}
|
||||
|
||||
<Box mt='auto'>
|
||||
{config.website.externalLinks.map(({ name, url }) => (
|
||||
<NavLink
|
||||
key={name}
|
||||
label={name}
|
||||
leftSection={<IconExternalLink size='1rem' />}
|
||||
variant='light'
|
||||
component={Link}
|
||||
href={url}
|
||||
target='_blank'
|
||||
/>
|
||||
))}
|
||||
</Box>
|
||||
<ScrollArea mah={200} mt='auto'>
|
||||
<Box>
|
||||
{config.website.externalLinks.map(({ name, url }, i) => (
|
||||
<NavLink
|
||||
key={i}
|
||||
label={name}
|
||||
leftSection={<IconExternalLink size='1rem' />}
|
||||
variant='light'
|
||||
component={Link}
|
||||
href={url}
|
||||
target='_blank'
|
||||
/>
|
||||
))}
|
||||
</Box>
|
||||
</ScrollArea>
|
||||
</AppShell.Navbar>
|
||||
|
||||
<AppShell.Main>
|
||||
|
||||
@@ -266,20 +266,26 @@ export default function FileModal({
|
||||
|
||||
<Combobox.Dropdown>
|
||||
<Combobox.Options>
|
||||
{tags?.map((tag) => (
|
||||
<Combobox.Option value={tag.id} key={tag.id} active={value.includes(tag.id)}>
|
||||
<Group gap='sm'>
|
||||
<Checkbox
|
||||
checked={value.includes(tag.id)}
|
||||
onChange={() => {}}
|
||||
aria-hidden
|
||||
tabIndex={-1}
|
||||
style={{ pointerEvents: 'none' }}
|
||||
/>
|
||||
<TagPill tag={tag} />
|
||||
</Group>
|
||||
{tags?.length ? (
|
||||
tags?.map((tag) => (
|
||||
<Combobox.Option value={tag.id} key={tag.id} active={value.includes(tag.id)}>
|
||||
<Group gap='sm'>
|
||||
<Checkbox
|
||||
checked={value.includes(tag.id)}
|
||||
onChange={() => {}}
|
||||
aria-hidden
|
||||
tabIndex={-1}
|
||||
style={{ pointerEvents: 'none' }}
|
||||
/>
|
||||
<TagPill tag={tag} />
|
||||
</Group>
|
||||
</Combobox.Option>
|
||||
))
|
||||
) : (
|
||||
<Combobox.Option value='no-tags' disabled>
|
||||
No tags found, create one outside of this menu.
|
||||
</Combobox.Option>
|
||||
))}
|
||||
)}
|
||||
</Combobox.Options>
|
||||
</Combobox.Dropdown>
|
||||
</Combobox>
|
||||
@@ -350,7 +356,7 @@ export default function FileModal({
|
||||
<Group justify='space-between' mt='lg'>
|
||||
<Group>
|
||||
{!reduce && (
|
||||
<Text size='sm' c='gray'>
|
||||
<Text size='sm' c='dimmed'>
|
||||
{file.id}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Response } from '@/lib/api/response';
|
||||
import { Button, Paper, SimpleGrid, Switch, TextInput, Title } from '@mantine/core';
|
||||
import { bytes } from '@/lib/bytes';
|
||||
import { Button, LoadingOverlay, Paper, SimpleGrid, Switch, TextInput, Title } from '@mantine/core';
|
||||
import { useForm } from '@mantine/form';
|
||||
import { IconDeviceFloppy } from '@tabler/icons-react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useEffect } from 'react';
|
||||
import { settingsOnSubmit } from '../settingsOnSubmit';
|
||||
import { bytes } from '@/lib/bytes';
|
||||
|
||||
export default function ServerSettingsChunks({
|
||||
swr: { data, isLoading },
|
||||
@@ -34,17 +34,20 @@ export default function ServerSettingsChunks({
|
||||
}, [data]);
|
||||
|
||||
return (
|
||||
<Paper withBorder p='sm'>
|
||||
<Paper withBorder p='sm' pos='relative'>
|
||||
<LoadingOverlay visible={isLoading} />
|
||||
|
||||
<Title order={2}>Chunks</Title>
|
||||
|
||||
<form onSubmit={form.onSubmit(onSubmit)}>
|
||||
<SimpleGrid mt='md' cols={{ base: 1, md: 2 }} spacing='lg'>
|
||||
<Switch
|
||||
label='Enable Chunks'
|
||||
description='Enable chunked uploads.'
|
||||
{...form.getInputProps('chunksEnabled', { type: 'checkbox' })}
|
||||
/>
|
||||
<Switch
|
||||
mt='md'
|
||||
label='Enable Chunks'
|
||||
description='Enable chunked uploads.'
|
||||
{...form.getInputProps('chunksEnabled', { type: 'checkbox' })}
|
||||
/>
|
||||
|
||||
<SimpleGrid mt='md' cols={{ base: 1, md: 2 }} spacing='lg'>
|
||||
<TextInput
|
||||
label='Max Chunk Size'
|
||||
description='Maximum size of an upload before it is split into chunks.'
|
||||
@@ -62,13 +65,7 @@ export default function ServerSettingsChunks({
|
||||
/>
|
||||
</SimpleGrid>
|
||||
|
||||
<Button
|
||||
type='submit'
|
||||
color='blue'
|
||||
mt='md'
|
||||
loading={isLoading}
|
||||
leftSection={<IconDeviceFloppy size='1rem' />}
|
||||
>
|
||||
<Button type='submit' mt='md' loading={isLoading} leftSection={<IconDeviceFloppy size='1rem' />}>
|
||||
Save
|
||||
</Button>
|
||||
</form>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Response } from '@/lib/api/response';
|
||||
import { Button, Paper, SimpleGrid, Switch, TextInput, Title } from '@mantine/core';
|
||||
import { Button, LoadingOverlay, Paper, SimpleGrid, Switch, TextInput, Title } from '@mantine/core';
|
||||
import { useForm } from '@mantine/form';
|
||||
import { IconDeviceFloppy } from '@tabler/icons-react';
|
||||
import { useRouter } from 'next/router';
|
||||
@@ -43,17 +43,20 @@ export default function ServerSettingsCore({
|
||||
}, [data]);
|
||||
|
||||
return (
|
||||
<Paper withBorder p='sm'>
|
||||
<Paper withBorder p='sm' pos='relative'>
|
||||
<LoadingOverlay visible={isLoading} />
|
||||
|
||||
<Title order={2}>Core</Title>
|
||||
|
||||
<form onSubmit={form.onSubmit(onSubmit)}>
|
||||
<SimpleGrid mt='md' cols={{ base: 1, md: 2 }} spacing='lg'>
|
||||
<Switch
|
||||
label='Return HTTPS URLs'
|
||||
description='Return URLs with HTTPS protocol.'
|
||||
{...form.getInputProps('coreReturnHttpsUrls', { type: 'checkbox' })}
|
||||
/>
|
||||
<Switch
|
||||
mt='md'
|
||||
label='Return HTTPS URLs'
|
||||
description='Return URLs with HTTPS protocol.'
|
||||
{...form.getInputProps('coreReturnHttpsUrls', { type: 'checkbox' })}
|
||||
/>
|
||||
|
||||
<SimpleGrid mt='md' cols={{ base: 1, md: 2 }} spacing='lg'>
|
||||
<TextInput
|
||||
label='Default Domain'
|
||||
description='The domain to use when generating URLs.'
|
||||
@@ -69,13 +72,7 @@ export default function ServerSettingsCore({
|
||||
/>
|
||||
</SimpleGrid>
|
||||
|
||||
<Button
|
||||
type='submit'
|
||||
color='blue'
|
||||
mt='md'
|
||||
loading={isLoading}
|
||||
leftSection={<IconDeviceFloppy size='1rem' />}
|
||||
>
|
||||
<Button type='submit' mt='md' loading={isLoading} leftSection={<IconDeviceFloppy size='1rem' />}>
|
||||
Save
|
||||
</Button>
|
||||
</form>
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
import { Response } from '@/lib/api/response';
|
||||
import { Button, Collapse, ColorInput, Paper, SimpleGrid, Switch, TextInput, Title } from '@mantine/core';
|
||||
import {
|
||||
Button,
|
||||
Collapse,
|
||||
ColorInput,
|
||||
LoadingOverlay,
|
||||
Paper,
|
||||
SimpleGrid,
|
||||
Switch,
|
||||
TextInput,
|
||||
Title,
|
||||
} from '@mantine/core';
|
||||
import { useForm } from '@mantine/form';
|
||||
import { IconDeviceFloppy } from '@tabler/icons-react';
|
||||
import { useRouter } from 'next/router';
|
||||
@@ -159,7 +169,9 @@ export default function ServerSettingsDiscord({
|
||||
}, [data]);
|
||||
|
||||
return (
|
||||
<Paper withBorder p='sm'>
|
||||
<Paper withBorder p='sm' pos='relative'>
|
||||
<LoadingOverlay visible={isLoading} />
|
||||
|
||||
<Title order={2}>Discord Webhook</Title>
|
||||
|
||||
<form onSubmit={formMain.onSubmit(onSubmitMain)}>
|
||||
@@ -186,13 +198,7 @@ export default function ServerSettingsDiscord({
|
||||
/>
|
||||
</SimpleGrid>
|
||||
|
||||
<Button
|
||||
type='submit'
|
||||
color='blue'
|
||||
mt='md'
|
||||
loading={isLoading}
|
||||
leftSection={<IconDeviceFloppy size='1rem' />}
|
||||
>
|
||||
<Button type='submit' mt='md' loading={isLoading} leftSection={<IconDeviceFloppy size='1rem' />}>
|
||||
Save
|
||||
</Button>
|
||||
</form>
|
||||
@@ -285,13 +291,7 @@ export default function ServerSettingsDiscord({
|
||||
</Paper>
|
||||
</Collapse>
|
||||
|
||||
<Button
|
||||
type='submit'
|
||||
color='blue'
|
||||
mt='md'
|
||||
loading={isLoading}
|
||||
leftSection={<IconDeviceFloppy size='1rem' />}
|
||||
>
|
||||
<Button type='submit' mt='md' loading={isLoading} leftSection={<IconDeviceFloppy size='1rem' />}>
|
||||
Save
|
||||
</Button>
|
||||
</form>
|
||||
@@ -387,13 +387,7 @@ export default function ServerSettingsDiscord({
|
||||
</Paper>
|
||||
</Collapse>
|
||||
|
||||
<Button
|
||||
type='submit'
|
||||
color='blue'
|
||||
mt='md'
|
||||
loading={isLoading}
|
||||
leftSection={<IconDeviceFloppy size='1rem' />}
|
||||
>
|
||||
<Button type='submit' mt='md' loading={isLoading} leftSection={<IconDeviceFloppy size='1rem' />}>
|
||||
Save
|
||||
</Button>
|
||||
</form>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Response } from '@/lib/api/response';
|
||||
import { Button, NumberInput, Paper, SimpleGrid, Switch, Title } from '@mantine/core';
|
||||
import { Button, LoadingOverlay, NumberInput, Paper, SimpleGrid, Switch, Title } from '@mantine/core';
|
||||
import { useForm } from '@mantine/form';
|
||||
import { IconCpu, IconDeviceFloppy } from '@tabler/icons-react';
|
||||
import { IconDeviceFloppy } from '@tabler/icons-react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useEffect } from 'react';
|
||||
import { settingsOnSubmit } from '../settingsOnSubmit';
|
||||
@@ -47,19 +47,21 @@ export default function ServerSettingsFeatures({
|
||||
}, [data]);
|
||||
|
||||
return (
|
||||
<Paper withBorder p='sm'>
|
||||
<Paper withBorder p='sm' pos='relative'>
|
||||
<LoadingOverlay visible={isLoading} />
|
||||
|
||||
<Title order={2}>Features</Title>
|
||||
|
||||
<form onSubmit={form.onSubmit(onSubmit)}>
|
||||
<SimpleGrid mt='md' cols={{ base: 1, md: 2 }} spacing='lg'>
|
||||
<Switch
|
||||
label='Image Compression'
|
||||
description='Automatically compresses images uploaded to the server.'
|
||||
description='Allows the ability for users to compress images.'
|
||||
{...form.getInputProps('featuresImageCompression', { type: 'checkbox' })}
|
||||
/>
|
||||
|
||||
<Switch
|
||||
label='Robots.txt'
|
||||
label='/robots.txt'
|
||||
description='Enables a robots.txt file for search engine optimization. Requires a server restart.'
|
||||
{...form.getInputProps('featuresRobotsTxt', { type: 'checkbox' })}
|
||||
/>
|
||||
@@ -84,30 +86,30 @@ export default function ServerSettingsFeatures({
|
||||
|
||||
<Switch
|
||||
label='Delete on Max Views'
|
||||
description='Automatically deletes files after they reach the maximum view count.'
|
||||
description='Automatically deletes files/urls after they reach the maximum view count. Requires a server restart.'
|
||||
{...form.getInputProps('featuresDeleteOnMaxViews', { type: 'checkbox' })}
|
||||
/>
|
||||
|
||||
<Switch
|
||||
label='Metrics Enabled'
|
||||
label='Enable Metrics'
|
||||
description='Enables metrics for the server. Requires a server restart.'
|
||||
{...form.getInputProps('featuresMetricsEnabled', { type: 'checkbox' })}
|
||||
/>
|
||||
|
||||
<Switch
|
||||
label='Metrics Admin Only'
|
||||
label='Admin Only Metrics'
|
||||
description='Requires an administrator to view metrics.'
|
||||
{...form.getInputProps('featuresMetricsAdminOnly', { type: 'checkbox' })}
|
||||
/>
|
||||
|
||||
<Switch
|
||||
label='Metrics Show User Specific'
|
||||
label='Show User Specific Metrics'
|
||||
description='Shows metrics specific to each user, for all users.'
|
||||
{...form.getInputProps('featuresMetricsShowUserSpecific', { type: 'checkbox' })}
|
||||
/>
|
||||
|
||||
<Switch
|
||||
label='Thumbnails Enabled'
|
||||
label='Enable Thumbnails'
|
||||
description='Enables thumbnail generation for images. Requires a server restart.'
|
||||
{...form.getInputProps('featuresThumbnailsEnabled', { type: 'checkbox' })}
|
||||
/>
|
||||
@@ -118,18 +120,11 @@ export default function ServerSettingsFeatures({
|
||||
placeholder='Enter a number...'
|
||||
min={1}
|
||||
max={16}
|
||||
leftSection={<IconCpu size='1rem' />}
|
||||
{...form.getInputProps('featuresThumbnailsNumberThreads')}
|
||||
/>
|
||||
</SimpleGrid>
|
||||
|
||||
<Button
|
||||
type='submit'
|
||||
color='blue'
|
||||
mt='md'
|
||||
loading={isLoading}
|
||||
leftSection={<IconDeviceFloppy size='1rem' />}
|
||||
>
|
||||
<Button type='submit' mt='md' loading={isLoading} leftSection={<IconDeviceFloppy size='1rem' />}>
|
||||
Save
|
||||
</Button>
|
||||
</form>
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
import { Response } from '@/lib/api/response';
|
||||
import { Button, NumberInput, Paper, Select, SimpleGrid, Switch, TextInput, Title } from '@mantine/core';
|
||||
import {
|
||||
Button,
|
||||
LoadingOverlay,
|
||||
NumberInput,
|
||||
Paper,
|
||||
Select,
|
||||
SimpleGrid,
|
||||
Switch,
|
||||
TextInput,
|
||||
Title,
|
||||
} from '@mantine/core';
|
||||
import { useForm } from '@mantine/form';
|
||||
import { IconDeviceFloppy } from '@tabler/icons-react';
|
||||
import { useRouter } from 'next/router';
|
||||
@@ -74,7 +84,9 @@ export default function ServerSettingsFiles({
|
||||
}, [data]);
|
||||
|
||||
return (
|
||||
<Paper withBorder p='sm'>
|
||||
<Paper withBorder p='sm' pos='relative'>
|
||||
<LoadingOverlay visible={isLoading} />
|
||||
|
||||
<Title order={2}>Files</Title>
|
||||
|
||||
<form onSubmit={form.onSubmit(onSubmit)}>
|
||||
@@ -143,13 +155,7 @@ export default function ServerSettingsFiles({
|
||||
/>
|
||||
</SimpleGrid>
|
||||
|
||||
<Button
|
||||
type='submit'
|
||||
color='blue'
|
||||
mt='md'
|
||||
loading={isLoading}
|
||||
leftSection={<IconDeviceFloppy size='1rem' />}
|
||||
>
|
||||
<Button type='submit' mt='md' loading={isLoading} leftSection={<IconDeviceFloppy size='1rem' />}>
|
||||
Save
|
||||
</Button>
|
||||
</form>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Response } from '@/lib/api/response';
|
||||
import { Button, Paper, SimpleGrid, TextInput, Title } from '@mantine/core';
|
||||
import { Button, LoadingOverlay, Paper, SimpleGrid, TextInput, Title } from '@mantine/core';
|
||||
import { useForm } from '@mantine/form';
|
||||
import { IconDeviceFloppy } from '@tabler/icons-react';
|
||||
import { useRouter } from 'next/router';
|
||||
@@ -43,7 +43,9 @@ export default function ServerSettingsHttpWebhook({
|
||||
}, [data]);
|
||||
|
||||
return (
|
||||
<Paper withBorder p='sm'>
|
||||
<Paper withBorder p='sm' pos='relative'>
|
||||
<LoadingOverlay visible={isLoading} />
|
||||
|
||||
<Title order={2}>HTTP Webhooks</Title>
|
||||
|
||||
<form onSubmit={form.onSubmit(onSubmit)}>
|
||||
@@ -63,13 +65,7 @@ export default function ServerSettingsHttpWebhook({
|
||||
/>
|
||||
</SimpleGrid>
|
||||
|
||||
<Button
|
||||
type='submit'
|
||||
color='blue'
|
||||
mt='md'
|
||||
loading={isLoading}
|
||||
leftSection={<IconDeviceFloppy size='1rem' />}
|
||||
>
|
||||
<Button type='submit' mt='md' loading={isLoading} leftSection={<IconDeviceFloppy size='1rem' />}>
|
||||
Save
|
||||
</Button>
|
||||
</form>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Response } from '@/lib/api/response';
|
||||
import { Button, NumberInput, Paper, SimpleGrid, Switch, Title } from '@mantine/core';
|
||||
import { Button, LoadingOverlay, NumberInput, Paper, SimpleGrid, Switch, Title } from '@mantine/core';
|
||||
import { useForm } from '@mantine/form';
|
||||
import { IconDeviceFloppy } from '@tabler/icons-react';
|
||||
import { useRouter } from 'next/router';
|
||||
@@ -31,15 +31,17 @@ export default function ServerSettingsInvites({
|
||||
}, [data]);
|
||||
|
||||
return (
|
||||
<Paper withBorder p='sm' h='100%'>
|
||||
<Paper withBorder p='sm' pos='relative' h='100%'>
|
||||
<LoadingOverlay visible={isLoading} />
|
||||
|
||||
<Title order={2}>Invites</Title>
|
||||
|
||||
<form onSubmit={form.onSubmit(onSubmit)}>
|
||||
<SimpleGrid mt='md' cols={{ base: 1, md: 2 }} spacing='lg'>
|
||||
<Switch
|
||||
label='Enable Chunks'
|
||||
description='Enable chunked uploads.'
|
||||
{...form.getInputProps('chunksEnabled', { type: 'checkbox' })}
|
||||
label='Enable Invites'
|
||||
description='Enable the use of invite links to register new users.'
|
||||
{...form.getInputProps('invitesEnabled', { type: 'checkbox' })}
|
||||
/>
|
||||
|
||||
<NumberInput
|
||||
@@ -48,17 +50,12 @@ export default function ServerSettingsInvites({
|
||||
placeholder='6'
|
||||
min={1}
|
||||
max={64}
|
||||
disabled={!form.values.invitesEnabled}
|
||||
{...form.getInputProps('invitesLength')}
|
||||
/>
|
||||
</SimpleGrid>
|
||||
|
||||
<Button
|
||||
type='submit'
|
||||
color='blue'
|
||||
mt='md'
|
||||
loading={isLoading}
|
||||
leftSection={<IconDeviceFloppy size='1rem' />}
|
||||
>
|
||||
<Button type='submit' mt='md' loading={isLoading} leftSection={<IconDeviceFloppy size='1rem' />}>
|
||||
Save
|
||||
</Button>
|
||||
</form>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Response } from '@/lib/api/response';
|
||||
import { Button, Paper, SimpleGrid, Switch, TextInput, Title } from '@mantine/core';
|
||||
import { Button, LoadingOverlay, Paper, SimpleGrid, Switch, TextInput, Title } from '@mantine/core';
|
||||
import { useForm } from '@mantine/form';
|
||||
import { IconDeviceFloppy } from '@tabler/icons-react';
|
||||
import { useRouter } from 'next/router';
|
||||
@@ -33,14 +33,16 @@ export default function ServerSettingsMfa({
|
||||
}, [data]);
|
||||
|
||||
return (
|
||||
<Paper withBorder p='sm'>
|
||||
<Paper withBorder p='sm' pos='relative'>
|
||||
<LoadingOverlay visible={isLoading} />
|
||||
|
||||
<Title order={2}>Multi-Factor Authentication</Title>
|
||||
|
||||
<form onSubmit={form.onSubmit(onSubmit)}>
|
||||
<SimpleGrid mt='md' cols={{ base: 1, md: 2 }} spacing='lg'>
|
||||
<Switch
|
||||
label='Passkeys'
|
||||
description='Enable the use of passwordless login with the use of WebAuthn passkeys like your phone, security, etc.'
|
||||
description='Enable the use of passwordless login with the use of WebAuthn passkeys like your phone, security keys, etc.'
|
||||
{...form.getInputProps('mfaPasskeys', { type: 'checkbox' })}
|
||||
/>
|
||||
|
||||
@@ -57,13 +59,7 @@ export default function ServerSettingsMfa({
|
||||
/>
|
||||
</SimpleGrid>
|
||||
|
||||
<Button
|
||||
type='submit'
|
||||
color='blue'
|
||||
mt='md'
|
||||
loading={isLoading}
|
||||
leftSection={<IconDeviceFloppy size='1rem' />}
|
||||
>
|
||||
<Button type='submit' mt='md' loading={isLoading} leftSection={<IconDeviceFloppy size='1rem' />}>
|
||||
Save
|
||||
</Button>
|
||||
</form>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Response } from '@/lib/api/response';
|
||||
import { Button, Paper, SimpleGrid, Switch, Text, TextInput, Title } from '@mantine/core';
|
||||
import { Button, LoadingOverlay, Paper, SimpleGrid, Switch, TextInput, Title } from '@mantine/core';
|
||||
import { useForm } from '@mantine/form';
|
||||
import { IconDeviceFloppy } from '@tabler/icons-react';
|
||||
import { useRouter } from 'next/router';
|
||||
@@ -77,7 +77,9 @@ export default function ServerSettingsOauth({
|
||||
}, [data]);
|
||||
|
||||
return (
|
||||
<Paper withBorder p='sm'>
|
||||
<Paper withBorder p='sm' pos='relative'>
|
||||
<LoadingOverlay visible={isLoading} />
|
||||
|
||||
<Title order={2}>OAuth</Title>
|
||||
|
||||
<form onSubmit={form.onSubmit(onSubmit)}>
|
||||
@@ -95,17 +97,18 @@ export default function ServerSettingsOauth({
|
||||
/>
|
||||
</SimpleGrid>
|
||||
<SimpleGrid mt='md' cols={{ base: 1, md: 2 }} spacing='lg'>
|
||||
<Paper withBorder p='sm' my='md'>
|
||||
<Text size='md' fw={700}>
|
||||
<Paper withBorder p='sm'>
|
||||
<Title order={4} mb='sm'>
|
||||
Discord
|
||||
</Text>
|
||||
</Title>
|
||||
|
||||
<TextInput label='Discord Client ID' {...form.getInputProps('oauthDiscordClientId')} />
|
||||
<TextInput label='Discord Client Secret' {...form.getInputProps('oauthDiscordClientSecret')} />
|
||||
</Paper>
|
||||
<Paper withBorder p='sm' my='md'>
|
||||
<Text size='md' fw={700}>
|
||||
<Paper withBorder p='sm'>
|
||||
<Title order={4} mb='sm'>
|
||||
Google
|
||||
</Text>
|
||||
</Title>
|
||||
|
||||
<TextInput label='Google Client ID' {...form.getInputProps('oauthGoogleClientId')} />
|
||||
<TextInput label='Google Client Secret' {...form.getInputProps('oauthGoogleClientSecret')} />
|
||||
@@ -113,9 +116,7 @@ export default function ServerSettingsOauth({
|
||||
</SimpleGrid>
|
||||
|
||||
<Paper withBorder p='sm' my='md'>
|
||||
<Text size='md' fw={700}>
|
||||
GitHub
|
||||
</Text>
|
||||
<Title order={4}>GitHub</Title>
|
||||
|
||||
<SimpleGrid mt='md' cols={{ base: 1, md: 2 }} spacing='lg'>
|
||||
<TextInput label='GitHub Client ID' {...form.getInputProps('oauthGithubClientId')} />
|
||||
@@ -123,10 +124,8 @@ export default function ServerSettingsOauth({
|
||||
</SimpleGrid>
|
||||
</Paper>
|
||||
|
||||
<Paper withBorder p='sm' mt='md'>
|
||||
<Text size='md' fw={700}>
|
||||
OpenID Connect
|
||||
</Text>
|
||||
<Paper withBorder p='sm' my='md'>
|
||||
<Title order={4}>OpenID Connect</Title>
|
||||
|
||||
<SimpleGrid mt='md' cols={{ base: 1, md: 2 }} spacing='lg'>
|
||||
<TextInput label='OIDC Client ID' {...form.getInputProps('oauthOidcClientId')} />
|
||||
@@ -137,13 +136,7 @@ export default function ServerSettingsOauth({
|
||||
</SimpleGrid>
|
||||
</Paper>
|
||||
|
||||
<Button
|
||||
type='submit'
|
||||
color='blue'
|
||||
mt='md'
|
||||
loading={isLoading}
|
||||
leftSection={<IconDeviceFloppy size='1rem' />}
|
||||
>
|
||||
<Button type='submit' mt='md' loading={isLoading} leftSection={<IconDeviceFloppy size='1rem' />}>
|
||||
Save
|
||||
</Button>
|
||||
</form>
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
import { Response } from '@/lib/api/response';
|
||||
import { Button, NumberInput, Paper, SimpleGrid, Switch, Text, TextInput, Title } from '@mantine/core';
|
||||
import {
|
||||
Button,
|
||||
LoadingOverlay,
|
||||
NumberInput,
|
||||
Paper,
|
||||
SimpleGrid,
|
||||
Switch,
|
||||
Text,
|
||||
TextInput,
|
||||
Title,
|
||||
} from '@mantine/core';
|
||||
import { useForm } from '@mantine/form';
|
||||
import { IconDeviceFloppy } from '@tabler/icons-react';
|
||||
import { useRouter } from 'next/router';
|
||||
@@ -61,7 +71,9 @@ export default function ServerSettingsRatelimit({
|
||||
}, [data]);
|
||||
|
||||
return (
|
||||
<Paper withBorder p='sm'>
|
||||
<Paper withBorder p='sm' pos='relative'>
|
||||
<LoadingOverlay visible={isLoading} />
|
||||
|
||||
<Title order={2}>Ratelimit</Title>
|
||||
|
||||
<Text c='dimmed' size='sm'>
|
||||
@@ -110,13 +122,7 @@ export default function ServerSettingsRatelimit({
|
||||
/>
|
||||
</SimpleGrid>
|
||||
|
||||
<Button
|
||||
type='submit'
|
||||
color='blue'
|
||||
mt='md'
|
||||
loading={isLoading}
|
||||
leftSection={<IconDeviceFloppy size='1rem' />}
|
||||
>
|
||||
<Button type='submit' mt='md' loading={isLoading} leftSection={<IconDeviceFloppy size='1rem' />}>
|
||||
Save
|
||||
</Button>
|
||||
</form>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Response } from '@/lib/api/response';
|
||||
import { Button, Paper, SimpleGrid, Text, TextInput, Title } from '@mantine/core';
|
||||
import { Button, LoadingOverlay, Paper, SimpleGrid, Text, TextInput, Title } from '@mantine/core';
|
||||
import { useForm } from '@mantine/form';
|
||||
import { IconDeviceFloppy } from '@tabler/icons-react';
|
||||
import ms from 'ms';
|
||||
@@ -38,7 +38,9 @@ export default function ServerSettingsTasks({
|
||||
}, [data]);
|
||||
|
||||
return (
|
||||
<Paper withBorder p='sm'>
|
||||
<Paper withBorder p='sm' pos='relative'>
|
||||
<LoadingOverlay visible={isLoading} />
|
||||
|
||||
<Title order={2}>Tasks</Title>
|
||||
|
||||
<Text c='dimmed' size='sm'>
|
||||
@@ -76,13 +78,7 @@ export default function ServerSettingsTasks({
|
||||
/>
|
||||
</SimpleGrid>
|
||||
|
||||
<Button
|
||||
type='submit'
|
||||
color='blue'
|
||||
mt='md'
|
||||
loading={isLoading}
|
||||
leftSection={<IconDeviceFloppy size='1rem' />}
|
||||
>
|
||||
<Button type='submit' mt='md' loading={isLoading} leftSection={<IconDeviceFloppy size='1rem' />}>
|
||||
Save
|
||||
</Button>
|
||||
</form>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Response } from '@/lib/api/response';
|
||||
import { Button, NumberInput, Paper, SimpleGrid, TextInput, Title } from '@mantine/core';
|
||||
import { Button, LoadingOverlay, NumberInput, Paper, SimpleGrid, TextInput, Title } from '@mantine/core';
|
||||
import { useForm } from '@mantine/form';
|
||||
import { IconDeviceFloppy } from '@tabler/icons-react';
|
||||
import { useRouter } from 'next/router';
|
||||
@@ -31,7 +31,9 @@ export default function ServerSettingsUrls({
|
||||
}, [data]);
|
||||
|
||||
return (
|
||||
<Paper withBorder p='sm'>
|
||||
<Paper withBorder p='sm' pos='relative'>
|
||||
<LoadingOverlay visible={isLoading} />
|
||||
|
||||
<Title order={2}>URL Shortener</Title>
|
||||
|
||||
<form onSubmit={form.onSubmit(onSubmit)}>
|
||||
@@ -53,13 +55,7 @@ export default function ServerSettingsUrls({
|
||||
/>
|
||||
</SimpleGrid>
|
||||
|
||||
<Button
|
||||
type='submit'
|
||||
color='blue'
|
||||
mt='md'
|
||||
loading={isLoading}
|
||||
leftSection={<IconDeviceFloppy size='1rem' />}
|
||||
>
|
||||
<Button type='submit' mt='md' loading={isLoading} leftSection={<IconDeviceFloppy size='1rem' />}>
|
||||
Save
|
||||
</Button>
|
||||
</form>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Response } from '@/lib/api/response';
|
||||
import { Button, Paper, SimpleGrid, TextInput, Title } from '@mantine/core';
|
||||
import { Button, JsonInput, Paper, SimpleGrid, TextInput, Title } from '@mantine/core';
|
||||
import { useForm } from '@mantine/form';
|
||||
import { IconDeviceFloppy } from '@tabler/icons-react';
|
||||
import { useRouter } from 'next/router';
|
||||
@@ -30,6 +30,7 @@ export default function ServerSettingsWebsite({
|
||||
websiteExternalLinks: JSON.stringify(defaultExternalLinks),
|
||||
websiteLoginBackground: '',
|
||||
websiteDefaultAvatar: '',
|
||||
websiteTos: '',
|
||||
|
||||
websiteThemeDefault: 'system',
|
||||
websiteThemeDark: 'builtin:dark_gray',
|
||||
@@ -58,6 +59,7 @@ export default function ServerSettingsWebsite({
|
||||
values.websiteLoginBackground.trim() === '' ? null : values.websiteLoginBackground.trim();
|
||||
sendValues.websiteDefaultAvatar =
|
||||
values.websiteDefaultAvatar.trim() === '' ? null : values.websiteDefaultAvatar.trim();
|
||||
sendValues.websiteTos = values.websiteTos.trim() === '' ? null : values.websiteTos.trim();
|
||||
|
||||
sendValues.websiteThemeDefault = values.websiteThemeDefault.trim();
|
||||
sendValues.websiteThemeDark = values.websiteThemeDark.trim();
|
||||
@@ -73,9 +75,10 @@ export default function ServerSettingsWebsite({
|
||||
form.setValues({
|
||||
websiteTitle: data?.websiteTitle ?? 'Zipline',
|
||||
websiteTitleLogo: data?.websiteTitleLogo ?? '',
|
||||
websiteExternalLinks: JSON.stringify(data?.websiteExternalLinks ?? defaultExternalLinks),
|
||||
websiteExternalLinks: JSON.stringify(data?.websiteExternalLinks ?? defaultExternalLinks, null, 2),
|
||||
websiteLoginBackground: data?.websiteLoginBackground ?? '',
|
||||
websiteDefaultAvatar: data?.websiteDefaultAvatar ?? '',
|
||||
websiteTos: data?.websiteTos ?? '',
|
||||
websiteThemeDefault: data?.websiteThemeDefault ?? 'system',
|
||||
websiteThemeDark: data?.websiteThemeDark ?? 'builtin:dark_gray',
|
||||
websiteThemeLight: data?.websiteThemeLight ?? 'builtin:light_gray',
|
||||
@@ -102,10 +105,14 @@ export default function ServerSettingsWebsite({
|
||||
{...form.getInputProps('websiteTitleLogo')}
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
<JsonInput
|
||||
label='External Links'
|
||||
description='The external links to show in the footer. This must be valid JSON.'
|
||||
placeholder={JSON.stringify(defaultExternalLinks)}
|
||||
formatOnBlur
|
||||
minRows={1}
|
||||
maxRows={7}
|
||||
autosize
|
||||
placeholder={JSON.stringify(defaultExternalLinks, null, 2)}
|
||||
{...form.getInputProps('websiteExternalLinks')}
|
||||
/>
|
||||
|
||||
@@ -123,6 +130,13 @@ export default function ServerSettingsWebsite({
|
||||
{...form.getInputProps('websiteDefaultAvatar')}
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
label='Terms of Service'
|
||||
description='Path to a Markdown (.md) file to use for the terms of service.'
|
||||
placeholder='/zipline/TOS.md'
|
||||
{...form.getInputProps('websiteTos')}
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
label='Default Theme'
|
||||
description='The default theme to use for the website.'
|
||||
@@ -147,13 +161,7 @@ export default function ServerSettingsWebsite({
|
||||
/>
|
||||
</SimpleGrid>
|
||||
|
||||
<Button
|
||||
type='submit'
|
||||
color='blue'
|
||||
mt='md'
|
||||
loading={isLoading}
|
||||
leftSection={<IconDeviceFloppy size='1rem' />}
|
||||
>
|
||||
<Button type='submit' mt='md' loading={isLoading} leftSection={<IconDeviceFloppy size='1rem' />}>
|
||||
Save
|
||||
</Button>
|
||||
</form>
|
||||
|
||||
@@ -18,10 +18,12 @@ import {
|
||||
import { notifications } from '@mantine/notifications';
|
||||
import {
|
||||
IconChevronDown,
|
||||
IconDeviceFloppy,
|
||||
IconPhoto,
|
||||
IconPhotoCancel,
|
||||
IconPhotoUp,
|
||||
IconSettingsFilled,
|
||||
IconX,
|
||||
} from '@tabler/icons-react';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
@@ -152,11 +154,17 @@ export default function SettingsAvatar() {
|
||||
</Button>
|
||||
)}
|
||||
{currentAvatar && (
|
||||
<Button variant='outline' color='red' onClick={clearAvatar}>
|
||||
<Button leftSection={<IconX size='1rem' />} color='red' onClick={clearAvatar}>
|
||||
Remove Avatar
|
||||
</Button>
|
||||
)}
|
||||
<Button variant='outline' disabled={!avatar} onClick={saveAvatar}>
|
||||
|
||||
<Button
|
||||
type='submit'
|
||||
disabled={!avatar}
|
||||
leftSection={<IconDeviceFloppy size='1rem' />}
|
||||
onClick={saveAvatar}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</Group>
|
||||
|
||||
@@ -57,7 +57,6 @@ export default function SettingsExports() {
|
||||
<Button
|
||||
mt='sm'
|
||||
fullWidth
|
||||
color='blue'
|
||||
disabled={isLoading}
|
||||
onClick={handleNewExport}
|
||||
leftSection={<IconPlus size='1rem' />}
|
||||
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
} from '@mantine/core';
|
||||
import { useForm } from '@mantine/form';
|
||||
import { notifications } from '@mantine/notifications';
|
||||
import { IconCheck, IconFileX } from '@tabler/icons-react';
|
||||
import { IconCheck, IconDeviceFloppy, IconFileX } from '@tabler/icons-react';
|
||||
import { mutate } from 'swr';
|
||||
|
||||
export default function SettingsFileView() {
|
||||
@@ -116,11 +116,6 @@ export default function SettingsFileView() {
|
||||
{ value: 'center', label: 'Center' },
|
||||
{ value: 'right', label: 'Right' },
|
||||
]}
|
||||
// itemComponent={({ label, value, ...props }) => (
|
||||
// <Group position={value} {...props}>
|
||||
// {label}
|
||||
// </Group>
|
||||
// )}
|
||||
disabled={!form.values.enabled}
|
||||
{...form.getInputProps('align')}
|
||||
/>
|
||||
@@ -158,7 +153,7 @@ export default function SettingsFileView() {
|
||||
</SimpleGrid>
|
||||
|
||||
<Group justify='left' mt='sm'>
|
||||
<Button variant='outline' type='submit'>
|
||||
<Button type='submit' leftSection={<IconDeviceFloppy size='1rem' />}>
|
||||
Save
|
||||
</Button>
|
||||
</Group>
|
||||
|
||||
@@ -3,7 +3,8 @@ import { Response } from '@/lib/api/response';
|
||||
import { fetchApi } from '@/lib/fetchApi';
|
||||
import { findProvider } from '@/lib/oauth/providerUtil';
|
||||
import { useUserStore } from '@/lib/store/user';
|
||||
import { Button, ButtonProps, Group, Paper, Text, Title, useMantineTheme } from '@mantine/core';
|
||||
import { darken } from '@/lib/theme/color';
|
||||
import { Button, ButtonProps, Paper, SimpleGrid, Text, Title, useMantineTheme } from '@mantine/core';
|
||||
import { notifications } from '@mantine/notifications';
|
||||
import type { OAuthProviderType } from '@prisma/client';
|
||||
import {
|
||||
@@ -16,7 +17,6 @@ import {
|
||||
} from '@tabler/icons-react';
|
||||
import Link from 'next/link';
|
||||
import { mutate } from 'swr';
|
||||
import { darken } from '@/lib/theme/color';
|
||||
|
||||
import styles from './index.module.css';
|
||||
|
||||
@@ -99,12 +99,12 @@ export default function SettingsOAuth() {
|
||||
Manage your connected OAuth providers.
|
||||
</Text>
|
||||
|
||||
<Group mt='xs'>
|
||||
<SimpleGrid mt='xs' cols={{ base: 1, md: 2 }} spacing='lg'>
|
||||
{config.oauthEnabled.discord && <OAuthButton provider='DISCORD' linked={!!discordLinked} />}
|
||||
{config.oauthEnabled.github && <OAuthButton provider='GITHUB' linked={!!githubLinked} />}
|
||||
{config.oauthEnabled.google && <OAuthButton provider='GOOGLE' linked={!!googleLinked} />}
|
||||
{config.oauthEnabled.oidc && <OAuthButton provider='OIDC' linked={!!oidcLinked} />}
|
||||
</Group>
|
||||
</SimpleGrid>
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -28,21 +28,23 @@ export default function RequerySizeButton() {
|
||||
message: data.status,
|
||||
icon: <IconFileSearch size='1rem' />,
|
||||
});
|
||||
|
||||
modals.closeAll();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal title={<Title>Are you sure?</Title>} opened={open} onClose={() => setOpen(false)}>
|
||||
<Stack>
|
||||
<Stack mb='md'>
|
||||
<span>
|
||||
This will requery the size of every file stored within the database. Additionally you can use the
|
||||
options below to delete file that aren't found in the database as well as force updating the
|
||||
size of every file whether or not it has a size.
|
||||
options below.
|
||||
</span>
|
||||
|
||||
<Switch
|
||||
label='Force Update'
|
||||
description='Force update the size of every file, even if it already has a size set.'
|
||||
checked={forceUpdate}
|
||||
onChange={() => setForceUpdate((val) => !val)}
|
||||
color='red'
|
||||
@@ -50,6 +52,7 @@ export default function RequerySizeButton() {
|
||||
|
||||
<Switch
|
||||
label='Force Delete'
|
||||
description='Delete files that are not found in the database, or have a size of 0.'
|
||||
checked={forceDelete}
|
||||
onChange={() => setForceDelete((val) => !val)}
|
||||
color='red'
|
||||
|
||||
@@ -3,7 +3,7 @@ import { fetchApi } from '@/lib/fetchApi';
|
||||
import { Button, Paper, Text, Title } from '@mantine/core';
|
||||
import { modals } from '@mantine/modals';
|
||||
import { showNotification } from '@mantine/notifications';
|
||||
import { IconLogout, IconLogout2 } from '@tabler/icons-react';
|
||||
import { IconLogout } from '@tabler/icons-react';
|
||||
import useSWR from 'swr';
|
||||
|
||||
export default function SettingsSessions() {
|
||||
@@ -39,17 +39,17 @@ export default function SettingsSessions() {
|
||||
<Paper withBorder p='sm'>
|
||||
<Title order={2}>Sessions</Title>
|
||||
|
||||
<Text c='muted' mt='sm'>
|
||||
<Text c='dimmed' mt='sm'>
|
||||
You are currently logged into {isLoading ? '...' : data?.other?.length ?? '...'} other devices
|
||||
</Text>
|
||||
|
||||
<Button
|
||||
mt='sm'
|
||||
fullWidth
|
||||
color='red'
|
||||
mt='md'
|
||||
disabled={isLoading || !data?.other?.length}
|
||||
onClick={handleLogOutOfAllDevices}
|
||||
leftSection={<IconLogout2 size='1rem' />}
|
||||
leftSection={<IconLogout size='1rem' />}
|
||||
>
|
||||
Log out everywhere
|
||||
</Button>
|
||||
|
||||
@@ -5,10 +5,10 @@ import {
|
||||
ActionIcon,
|
||||
Button,
|
||||
CopyButton,
|
||||
Group,
|
||||
Paper,
|
||||
PasswordInput,
|
||||
ScrollArea,
|
||||
Text,
|
||||
TextInput,
|
||||
Title,
|
||||
Tooltip,
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
IconAsteriskSimple,
|
||||
IconCheck,
|
||||
IconCopy,
|
||||
IconDeviceFloppy,
|
||||
IconKey,
|
||||
IconUser,
|
||||
IconUserCancel,
|
||||
@@ -91,7 +92,11 @@ export default function SettingsUser() {
|
||||
|
||||
return (
|
||||
<Paper withBorder p='sm'>
|
||||
<Title order={2}>User info</Title>
|
||||
<Title order={2}>User Info</Title>
|
||||
<Text c='dimmed' size='sm' mb='sm'>
|
||||
{user?.id}
|
||||
</Text>
|
||||
|
||||
<form onSubmit={form.onSubmit(onSubmit)}>
|
||||
<TextInput
|
||||
rightSection={
|
||||
@@ -127,11 +132,9 @@ export default function SettingsUser() {
|
||||
leftSection={<IconAsteriskSimple size='1rem' />}
|
||||
/>
|
||||
|
||||
<Group justify='left' mt='sm'>
|
||||
<Button variant='outline' type='submit'>
|
||||
Save
|
||||
</Button>
|
||||
</Group>
|
||||
<Button type='submit' mt='md' loading={!user} leftSection={<IconDeviceFloppy size='1rem' />}>
|
||||
Save
|
||||
</Button>
|
||||
</form>
|
||||
</Paper>
|
||||
);
|
||||
|
||||
@@ -48,12 +48,12 @@ export function filesModal(
|
||||
</Group>
|
||||
<Group justify='right'>
|
||||
<Tooltip label='Open link in a new tab'>
|
||||
<ActionIcon onClick={() => open(idx)} variant='filled' color='primary'>
|
||||
<ActionIcon onClick={() => open(idx)} variant='filled'>
|
||||
<IconExternalLink size='1rem' />
|
||||
</ActionIcon>
|
||||
</Tooltip>
|
||||
<Tooltip label='Copy link to clipboard'>
|
||||
<ActionIcon onClick={() => copy(idx)} variant='filled' color='primary'>
|
||||
<ActionIcon onClick={() => copy(idx)} variant='filled'>
|
||||
<IconClipboardCopy size='1rem' />
|
||||
</ActionIcon>
|
||||
</Tooltip>
|
||||
|
||||
@@ -19,7 +19,7 @@ export async function deleteUser(user: User) {
|
||||
onConfirm: () =>
|
||||
modals.openConfirmModal({
|
||||
centered: true,
|
||||
title: <Title>Delete {user.username}&qpos;s data?</Title>,
|
||||
title: <Title>Delete {user.username}'s data?</Title>,
|
||||
children: `Would you like to delete ${user.username}'s files and urls? This action cannot be undone.`,
|
||||
labels: {
|
||||
cancel: 'No, keep everything & only delete user',
|
||||
|
||||
@@ -151,8 +151,6 @@ export const PROP_TO_ENV = {
|
||||
|
||||
'datasource.local.directory': 'DATASOURCE_LOCAL_DIRECTORY',
|
||||
|
||||
'website.tos': 'WEBSITE_TOS',
|
||||
|
||||
'ssl.key': 'SSL_KEY',
|
||||
'ssl.cert': 'SSL_CERT',
|
||||
};
|
||||
@@ -207,6 +205,7 @@ export const DATABASE_TO_PROP = {
|
||||
websiteExternalLinks: 'website.externalLinks',
|
||||
websiteLoginBackground: 'website.loginBackground',
|
||||
websiteDefaultAvatar: 'website.defaultAvatar',
|
||||
websiteTos: 'website.tos',
|
||||
|
||||
websiteThemeDefault: 'website.theme.default',
|
||||
websiteThemeDark: 'website.theme.dark',
|
||||
@@ -305,8 +304,6 @@ export function readEnv() {
|
||||
|
||||
env('datasource.local.directory', 'string'),
|
||||
|
||||
env('website.tos', 'string'),
|
||||
|
||||
env('ssl.key', 'string'),
|
||||
env('ssl.cert', 'string'),
|
||||
];
|
||||
|
||||
@@ -48,6 +48,29 @@ export function parseUserToken(
|
||||
export function ziplineAuth(options?: ZiplineAuthOptions) {
|
||||
return (handler: Handler) => {
|
||||
return async (req: NextApiReq, res: NextApiRes) => {
|
||||
const authorization = req.headers.authorization;
|
||||
|
||||
if (authorization) {
|
||||
try {
|
||||
// eslint-disable-next-line no-var
|
||||
var token = parseUserToken(authorization);
|
||||
} catch (e) {
|
||||
return res.unauthorized((e as { error: string }).error);
|
||||
}
|
||||
|
||||
const user = await prisma.user.findFirst({
|
||||
where: {
|
||||
token,
|
||||
},
|
||||
select: userSelect,
|
||||
});
|
||||
if (!user) return res.unauthorized('invalid authorization token');
|
||||
|
||||
req.user = user;
|
||||
|
||||
return handler(req, res);
|
||||
}
|
||||
|
||||
const session = await getSession(req, res);
|
||||
if (!session.id || !session.sessionId) return res.unauthorized('invalid session, not logged in');
|
||||
|
||||
|
||||
@@ -25,7 +25,8 @@ export function themeComponents(theme: ZiplineTheme): MantineThemeOverride {
|
||||
LoadingOverlay: LoadingOverlay.extend({
|
||||
defaultProps: {
|
||||
overlayProps: {
|
||||
opacity: 0.3,
|
||||
blur: 2,
|
||||
radius: 'sm',
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
||||
@@ -39,6 +39,29 @@ export function parseUserToken(
|
||||
}
|
||||
|
||||
export async function userMiddleware(req: FastifyRequest, res: FastifyReply) {
|
||||
const authorization = req.headers.authorization;
|
||||
|
||||
if (authorization) {
|
||||
try {
|
||||
// eslint-disable-next-line no-var
|
||||
var token = parseUserToken(authorization);
|
||||
} catch (e) {
|
||||
return res.unauthorized((e as { error: string }).error);
|
||||
}
|
||||
|
||||
const user = await prisma.user.findFirst({
|
||||
where: {
|
||||
token,
|
||||
},
|
||||
select: userSelect,
|
||||
});
|
||||
if (!user) return res.unauthorized('invalid authorization token');
|
||||
|
||||
req.user = user;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const session = await getSession(req, res);
|
||||
|
||||
if (!session.id || !session.sessionId) return res.unauthorized('not logged in');
|
||||
|
||||
@@ -6,7 +6,7 @@ import { readThemes } from '@/lib/theme/file';
|
||||
import { administratorMiddleware } from '@/server/middleware/administrator';
|
||||
import { userMiddleware } from '@/server/middleware/user';
|
||||
import fastifyPlugin from 'fastify-plugin';
|
||||
import { existsSync } from 'fs';
|
||||
import { statSync } from 'fs';
|
||||
import ms from 'ms';
|
||||
import { cpus } from 'os';
|
||||
import { z } from 'zod';
|
||||
@@ -16,6 +16,16 @@ type Settings = Awaited<ReturnType<typeof readDatabaseSettings>>;
|
||||
export type ApiServerSettingsResponse = Settings;
|
||||
type Body = Partial<Settings>;
|
||||
|
||||
const zMs = z
|
||||
.union([z.number().min(1), z.string()])
|
||||
.transform((value) => (typeof value === 'string' ? ms(value) : value))
|
||||
.refine((value) => value > 0, 'Value must be greater than 0');
|
||||
|
||||
const zBytes = z
|
||||
.union([z.number().min(1), z.string()])
|
||||
.transform((value) => (typeof value === 'string' ? bytes(value) : value))
|
||||
.refine((value) => value > 0, 'Value must be greater than 0');
|
||||
|
||||
const discordEmbed = z
|
||||
.union([
|
||||
z
|
||||
@@ -79,35 +89,25 @@ export default fastifyPlugin(
|
||||
|
||||
const settingsBodySchema = z
|
||||
.object({
|
||||
coreTempDirectory: z
|
||||
.string()
|
||||
.refine((dir) => !dir || existsSync(dir), 'temp directory does not exist'),
|
||||
coreTempDirectory: z.string().refine((dir) => {
|
||||
try {
|
||||
return !dir || statSync(dir).isDirectory();
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}, 'Directory does not exist'),
|
||||
coreDefaultDomain: z.string().nullable(),
|
||||
coreReturnHttpsUrls: z.boolean(),
|
||||
|
||||
chunksEnabled: z.boolean(),
|
||||
chunksMax: z
|
||||
.union([z.number(), z.string()])
|
||||
.transform((value) => (typeof value === 'string' ? bytes(value) : value)),
|
||||
chunksSize: z
|
||||
.union([z.number(), z.string()])
|
||||
.transform((value) => (typeof value === 'string' ? bytes(value) : value)),
|
||||
chunksMax: zBytes,
|
||||
chunksSize: zBytes,
|
||||
|
||||
tasksDeleteInterval: z
|
||||
.union([z.number(), z.string()])
|
||||
.transform((value) => (typeof value === 'string' ? ms(value) : value)),
|
||||
tasksClearInvitesInterval: z
|
||||
.union([z.number(), z.string()])
|
||||
.transform((value) => (typeof value === 'string' ? ms(value) : value)),
|
||||
tasksMaxViewsInterval: z
|
||||
.union([z.number(), z.string()])
|
||||
.transform((value) => (typeof value === 'string' ? ms(value) : value)),
|
||||
tasksThumbnailsInterval: z
|
||||
.union([z.number(), z.string()])
|
||||
.transform((value) => (typeof value === 'string' ? ms(value) : value)),
|
||||
tasksMetricsInterval: z
|
||||
.union([z.number(), z.string()])
|
||||
.transform((value) => (typeof value === 'string' ? ms(value) : value)),
|
||||
tasksDeleteInterval: zMs,
|
||||
tasksClearInvitesInterval: zMs,
|
||||
tasksMaxViewsInterval: zMs,
|
||||
tasksThumbnailsInterval: zMs,
|
||||
tasksMetricsInterval: zMs,
|
||||
|
||||
filesRoute: z.string().startsWith('/'),
|
||||
filesLength: z.number().min(1).max(64),
|
||||
@@ -117,13 +117,9 @@ export default fastifyPlugin(
|
||||
.transform((value) =>
|
||||
typeof value === 'string' ? value.split(',').map((ext) => ext.trim()) : value,
|
||||
),
|
||||
filesMaxFileSize: z
|
||||
.union([z.number(), z.string()])
|
||||
.transform((value) => (typeof value === 'string' ? bytes(value) : value)),
|
||||
filesDefaultExpiration: z
|
||||
.union([z.number(), z.string()])
|
||||
.nullable()
|
||||
.transform((value) => (typeof value === 'string' ? ms(value) : value)),
|
||||
filesMaxFileSize: zMs,
|
||||
|
||||
filesDefaultExpiration: zBytes,
|
||||
filesAssumeMimetypes: z.boolean(),
|
||||
filesDefaultDateFormat: z.string(),
|
||||
filesRemoveGpsMetadata: z.boolean(),
|
||||
@@ -143,7 +139,7 @@ export default fastifyPlugin(
|
||||
|
||||
featuresMetricsEnabled: z.boolean(),
|
||||
featuresMetricsAdminOnly: z.boolean(),
|
||||
feaeturesMetricsShowUserSpecific: z.boolean(),
|
||||
featuresMetricsShowUserSpecific: z.boolean(),
|
||||
|
||||
invitesEnabled: z.boolean(),
|
||||
invitesLength: z.number().min(1).max(64),
|
||||
@@ -163,6 +159,17 @@ export default fastifyPlugin(
|
||||
.transform((value) => (typeof value === 'string' ? JSON.parse(value) : value)),
|
||||
websiteLoginBackground: z.string().url().nullable(),
|
||||
websiteDefaultAvatar: z.string().url().nullable(),
|
||||
websiteTos: z
|
||||
.string()
|
||||
.nullable()
|
||||
.refine((input) => !input || input.endsWith('.md'), 'File is not a markdown file')
|
||||
.refine((input) => {
|
||||
try {
|
||||
return !input || statSync(input).isFile();
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}, 'File does not exist'),
|
||||
|
||||
websiteThemeDefault: z.enum(['system', ...themes]),
|
||||
websiteThemeDark: z.enum(themes as unknown as readonly [string, ...string[]]),
|
||||
@@ -188,7 +195,7 @@ export default fastifyPlugin(
|
||||
mfaPasskeys: z.boolean(),
|
||||
|
||||
ratelimitEnabled: z.boolean(),
|
||||
ratelimitMax: z.number(),
|
||||
ratelimitMax: z.number().refine((value) => value > 0, 'Value must be greater than 0'),
|
||||
ratelimitWindow: z.number().nullable(),
|
||||
ratelimitAdminBypass: z.boolean(),
|
||||
ratelimitAllowList: z
|
||||
@@ -264,7 +271,11 @@ export default fastifyPlugin(
|
||||
'oauthOidcUserinfoUrl',
|
||||
],
|
||||
},
|
||||
);
|
||||
)
|
||||
.refine((data) => !data.ratelimitWindow || (data.ratelimitMax && data.ratelimitMax > 0), {
|
||||
message: 'ratelimitMax must be set if ratelimitWindow is set',
|
||||
path: ['ratelimitMax'],
|
||||
});
|
||||
|
||||
const result = settingsBodySchema.safeParse(req.body);
|
||||
if (!result.success) {
|
||||
|
||||
@@ -56,7 +56,15 @@ export default fastifyPlugin(
|
||||
|
||||
const path = join(config.core.tempDirectory, exportDb.path);
|
||||
|
||||
await rm(path);
|
||||
try {
|
||||
await rm(path);
|
||||
} catch (e) {
|
||||
logger.warn(
|
||||
`failed to delete export file, it might already be deleted. ${exportDb.id}: ${exportDb.path}`,
|
||||
{ e },
|
||||
);
|
||||
}
|
||||
|
||||
await prisma.export.delete({ where: { id: req.query.id } });
|
||||
|
||||
logger.info(`deleted export ${exportDb.id}: ${exportDb.path}`);
|
||||
|
||||
Reference in New Issue
Block a user