WIP rahvatarkus, working CRUD demo
This commit is contained in:
parent
11ade8fc06
commit
1674cdd726
14 changed files with 1015 additions and 15 deletions
10
package.json
10
package.json
|
@ -27,34 +27,38 @@
|
|||
"@types/better-sqlite3": "^7.6.12",
|
||||
"@types/spotify-web-api-node": "^5.0.11",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"bits-ui": "1.0.0-next.86",
|
||||
"bits-ui": "1.0.0-next.94",
|
||||
"clsx": "^2.1.1",
|
||||
"drizzle-kit": "^0.30.2",
|
||||
"eslint": "^9.19.0",
|
||||
"eslint-config-prettier": "^10.0.1",
|
||||
"eslint-plugin-svelte": "^2.46.1",
|
||||
"formsnap": "^2.0.0",
|
||||
"globals": "^15.14.0",
|
||||
"lucide-svelte": "^0.474.0",
|
||||
"mode-watcher": "^0.5.1",
|
||||
"prettier": "^3.4.2",
|
||||
"prettier-plugin-svelte": "^3.3.3",
|
||||
"prettier-plugin-tailwindcss": "^0.6.10",
|
||||
"svelte": "^5.19.1",
|
||||
"svelte-check": "^4.1.4",
|
||||
"svelte-dnd-action": "^0.9.55",
|
||||
"svelte-sonner": "^0.3.28",
|
||||
"sveltekit-superforms": "^2.23.1",
|
||||
"tailwind-merge": "^2.6.0",
|
||||
"tailwind-variants": "^0.3.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"typescript": "^5.7.3",
|
||||
"typescript-eslint": "^8.22.0",
|
||||
"vite": "^6.0.11"
|
||||
"vite": "^6.0.11",
|
||||
"zod": "^3.24.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fontsource-variable/kode-mono": "^5.1.1",
|
||||
"@fontsource-variable/smooch-sans": "^5.1.1",
|
||||
"better-sqlite3": "^11.8.0",
|
||||
"drizzle-orm": "^0.38.4",
|
||||
"mode-watcher": "^0.5.1",
|
||||
"nanoid": "^5.0.9",
|
||||
"spotify-web-api-node": "^5.0.2",
|
||||
"svelte-kit-sessions": "^0.4.0"
|
||||
|
|
465
pnpm-lock.yaml
generated
465
pnpm-lock.yaml
generated
|
@ -20,9 +20,6 @@ importers:
|
|||
drizzle-orm:
|
||||
specifier: ^0.38.4
|
||||
version: 0.38.4(@types/better-sqlite3@7.6.12)(better-sqlite3@11.8.1)
|
||||
mode-watcher:
|
||||
specifier: ^0.5.1
|
||||
version: 0.5.1(svelte@5.19.1)
|
||||
nanoid:
|
||||
specifier: ^5.0.9
|
||||
version: 5.0.9
|
||||
|
@ -67,8 +64,8 @@ importers:
|
|||
specifier: ^10.4.20
|
||||
version: 10.4.20(postcss@8.5.1)
|
||||
bits-ui:
|
||||
specifier: 1.0.0-next.86
|
||||
version: 1.0.0-next.86(svelte@5.19.1)
|
||||
specifier: 1.0.0-next.94
|
||||
version: 1.0.0-next.94(svelte@5.19.1)
|
||||
clsx:
|
||||
specifier: ^2.1.1
|
||||
version: 2.1.1
|
||||
|
@ -84,12 +81,18 @@ importers:
|
|||
eslint-plugin-svelte:
|
||||
specifier: ^2.46.1
|
||||
version: 2.46.1(eslint@9.19.0(jiti@1.21.7))(svelte@5.19.1)
|
||||
formsnap:
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0(svelte@5.19.1)(sveltekit-superforms@2.23.1(@sveltejs/kit@2.16.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.1)(vite@6.0.11(@types/node@22.13.1)(jiti@1.21.7)(yaml@2.7.0)))(svelte@5.19.1)(vite@6.0.11(@types/node@22.13.1)(jiti@1.21.7)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.19.1)(typescript@5.7.3))
|
||||
globals:
|
||||
specifier: ^15.14.0
|
||||
version: 15.14.0
|
||||
lucide-svelte:
|
||||
specifier: ^0.474.0
|
||||
version: 0.474.0(svelte@5.19.1)
|
||||
mode-watcher:
|
||||
specifier: ^0.5.1
|
||||
version: 0.5.1(svelte@5.19.1)
|
||||
prettier:
|
||||
specifier: ^3.4.2
|
||||
version: 3.4.2
|
||||
|
@ -108,6 +111,12 @@ importers:
|
|||
svelte-dnd-action:
|
||||
specifier: ^0.9.55
|
||||
version: 0.9.55(svelte@5.19.1)
|
||||
svelte-sonner:
|
||||
specifier: ^0.3.28
|
||||
version: 0.3.28(svelte@5.19.1)
|
||||
sveltekit-superforms:
|
||||
specifier: ^2.23.1
|
||||
version: 2.23.1(@sveltejs/kit@2.16.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.1)(vite@6.0.11(@types/node@22.13.1)(jiti@1.21.7)(yaml@2.7.0)))(svelte@5.19.1)(vite@6.0.11(@types/node@22.13.1)(jiti@1.21.7)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.19.1)(typescript@5.7.3)
|
||||
tailwind-merge:
|
||||
specifier: ^2.6.0
|
||||
version: 2.6.0
|
||||
|
@ -129,6 +138,9 @@ importers:
|
|||
vite:
|
||||
specifier: ^6.0.11
|
||||
version: 6.0.11(@types/node@22.13.1)(jiti@1.21.7)(yaml@2.7.0)
|
||||
zod:
|
||||
specifier: ^3.24.1
|
||||
version: 3.24.1
|
||||
|
||||
packages:
|
||||
|
||||
|
@ -140,6 +152,16 @@ packages:
|
|||
resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
|
||||
'@ark/schema@0.39.0':
|
||||
resolution: {integrity: sha512-LQbQUb3Sj461LgklXObAyUJNtsUUCBxZlO2HqRLYvRSqpStm0xTMrXn51DwBNNxeSULvKVpXFwoxiSec9kwKww==}
|
||||
|
||||
'@ark/util@0.39.0':
|
||||
resolution: {integrity: sha512-90APHVklk8BP4kku7hIh1BgrhuyKYqoZ4O7EybtFRo7cDl9mIyc/QUbGvYDg//73s0J2H0I/gW9pzroA1R4IBQ==}
|
||||
|
||||
'@babel/runtime@7.26.7':
|
||||
resolution: {integrity: sha512-AOPI3D+a8dXnja+iwsUqGRjr1BbZIe771sXdapOtYI531gSqpi92vXivKcq2asu/DFpdl1ceFAKZyRzK2PCVcQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@drizzle-team/brocli@0.10.2':
|
||||
resolution: {integrity: sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==}
|
||||
|
||||
|
@ -617,6 +639,9 @@ packages:
|
|||
resolution: {integrity: sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@exodus/schemasafe@1.3.0':
|
||||
resolution: {integrity: sha512-5Aap/GaRupgNx/feGBwLLTVv8OQFfv3pq2lPRzPg9R+IOBnDgghTGW7l7EuVXOvg5cc/xSAlRW8rBrjIC3Nvqw==}
|
||||
|
||||
'@floating-ui/core@1.6.9':
|
||||
resolution: {integrity: sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==}
|
||||
|
||||
|
@ -632,6 +657,16 @@ packages:
|
|||
'@fontsource-variable/smooch-sans@5.1.1':
|
||||
resolution: {integrity: sha512-ADcY3Pjkvu74x4T+p2gNIo8Ba7DGrX1IhQgJFefztWB8Tf5nX7Qb+tqAbtW7O/KYWJi4EjzrxCefHBM1PfOOsg==}
|
||||
|
||||
'@gcornut/valibot-json-schema@0.31.0':
|
||||
resolution: {integrity: sha512-3xGptCurm23e7nuPQkdrE5rEs1FeTPHhAUsBuwwqG4/YeZLwJOoYZv+fmsppUEfo5y9lzUwNQrNqLS/q7HMc7g==}
|
||||
hasBin: true
|
||||
|
||||
'@hapi/hoek@9.3.0':
|
||||
resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==}
|
||||
|
||||
'@hapi/topo@5.1.0':
|
||||
resolution: {integrity: sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==}
|
||||
|
||||
'@humanfs/core@0.19.1':
|
||||
resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==}
|
||||
engines: {node: '>=18.18.0'}
|
||||
|
@ -805,6 +840,10 @@ packages:
|
|||
'@polka/url@1.0.0-next.28':
|
||||
resolution: {integrity: sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==}
|
||||
|
||||
'@poppinss/macroable@1.0.4':
|
||||
resolution: {integrity: sha512-ct43jurbe7lsUX5eIrj4ijO3j/6zIPp7CDnFWXDs7UPAbw1Pu1iH3oAmFdP4jcskKJBURH5M9oTtyeiUXyHX8Q==}
|
||||
engines: {node: '>=18.16.0'}
|
||||
|
||||
'@rollup/plugin-commonjs@28.0.2':
|
||||
resolution: {integrity: sha512-BEFI2EDqzl+vA1rl97IDRZ61AIwGH093d9nz8+dThxJNH8oSoB7MjWvPCX3dkaK1/RCJ/1v/R1XB15FuSs0fQw==}
|
||||
engines: {node: '>=16.0.0 || 14 >= 14.17'}
|
||||
|
@ -936,6 +975,18 @@ packages:
|
|||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@sideway/address@4.1.5':
|
||||
resolution: {integrity: sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==}
|
||||
|
||||
'@sideway/formula@3.0.1':
|
||||
resolution: {integrity: sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==}
|
||||
|
||||
'@sideway/pinpoint@2.0.0':
|
||||
resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==}
|
||||
|
||||
'@sinclair/typebox@0.34.16':
|
||||
resolution: {integrity: sha512-rIljj8VPYAfn26ANY+5pCNVBPiv6hSufuKGe46y65cJZpvx8vHvPXlU0Q/Le4OGtlNaL8Jg2FuhtvQX18lSIqA==}
|
||||
|
||||
'@sveltejs/adapter-node@5.2.12':
|
||||
resolution: {integrity: sha512-0bp4Yb3jKIEcZWVcJC/L1xXp9zzJS4hDwfb4VITAkfT4OVdkspSHsx7YhqJDbb2hgLl6R9Vs7VQR+fqIVOxPUQ==}
|
||||
peerDependencies:
|
||||
|
@ -1008,6 +1059,25 @@ packages:
|
|||
'@types/spotify-web-api-node@5.0.11':
|
||||
resolution: {integrity: sha512-RS3IkSqH9geC61e8qd+Oy7giOTtiY7ywm0Z4bu5uYuc7XuOcLfDwKjmle85IbpTEdazeCgmIbo8nMLg7WDVvgw==}
|
||||
|
||||
'@types/validator@13.12.2':
|
||||
resolution: {integrity: sha512-6SlHBzUW8Jhf3liqrGGXyTJSIFe4nqlJ5A5KaMZ2l/vbM3Wh3KSybots/wfWVzNLK4D1NZluDlSQIbIEPx6oyA==}
|
||||
|
||||
'@typeschema/class-validator@0.3.0':
|
||||
resolution: {integrity: sha512-OJSFeZDIQ8EK1HTljKLT5CItM2wsbgczLN8tMEfz3I1Lmhc5TBfkZ0eikFzUC16tI3d1Nag7um6TfCgp2I2Bww==}
|
||||
peerDependencies:
|
||||
class-validator: ^0.14.1
|
||||
peerDependenciesMeta:
|
||||
class-validator:
|
||||
optional: true
|
||||
|
||||
'@typeschema/core@0.14.0':
|
||||
resolution: {integrity: sha512-Ia6PtZHcL3KqsAWXjMi5xIyZ7XMH4aSnOQes8mfMLx+wGFGtGRNlwe6Y7cYvX+WfNK67OL0/HSe9t8QDygV0/w==}
|
||||
peerDependencies:
|
||||
'@types/json-schema': ^7.0.15
|
||||
peerDependenciesMeta:
|
||||
'@types/json-schema':
|
||||
optional: true
|
||||
|
||||
'@typescript-eslint/eslint-plugin@8.22.0':
|
||||
resolution: {integrity: sha512-4Uta6REnz/xEJMvwf72wdUnC3rr4jAQf5jnTkeRQ9b6soxLxhDEbS/pfMPoJLDfFPNVRdryqWUIV/2GZzDJFZw==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
@ -1055,6 +1125,14 @@ packages:
|
|||
resolution: {integrity: sha512-AWpYAXnUgvLNabGTy3uBylkgZoosva/miNd1I8Bz3SjotmQPbVqhO4Cczo8AsZ44XVErEBPr/CRSgaj8sG7g0w==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@vinejs/compiler@3.0.0':
|
||||
resolution: {integrity: sha512-v9Lsv59nR56+bmy2p0+czjZxsLHwaibJ+SV5iK9JJfehlJMa501jUJQqqz4X/OqKXrxtE3uTQmSqjUqzF3B2mw==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
|
||||
'@vinejs/vine@3.0.0':
|
||||
resolution: {integrity: sha512-GeCAHLzKkL2kMFqatgqyiiNh+FILOSAV8x8imBDo6AWQ91w30Kaxw4FnzUDqgcd9z8aCYOBQ7RJxBBGfyr+USQ==}
|
||||
engines: {node: '>=18.16.0'}
|
||||
|
||||
acorn-jsx@5.3.2:
|
||||
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
|
||||
peerDependencies:
|
||||
|
@ -1106,6 +1184,9 @@ packages:
|
|||
resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
arktype@2.0.4:
|
||||
resolution: {integrity: sha512-S68rWVDnJauwH7/QCm8zCUM3aTe9Xk6oRihdcc3FSUAtxCo/q1Fwq46JhcwB5Ufv1YStwdQRz+00Y/URlvbhAQ==}
|
||||
|
||||
asynckit@0.4.0:
|
||||
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
|
||||
|
||||
|
@ -1136,8 +1217,8 @@ packages:
|
|||
bindings@1.5.0:
|
||||
resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==}
|
||||
|
||||
bits-ui@1.0.0-next.86:
|
||||
resolution: {integrity: sha512-C2sTO3sasGoRhoMG2CUUsGfOhAoRL5Jc4pVB6AxoKQ+FBmX/uG9K1tW44eT/801iMoH+QeaH6fNCnoshpZtS8A==}
|
||||
bits-ui@1.0.0-next.94:
|
||||
resolution: {integrity: sha512-aGr6iMg16olEVFDYOUDfMB/uvExdmFuNLeILxv3MkwD3plTIbBBanA5/KLVfEnzT0uFgoEIrDV/unLfLG/BmEQ==}
|
||||
engines: {node: '>=18', pnpm: '>=8.7.0'}
|
||||
peerDependencies:
|
||||
svelte: ^5.11.0
|
||||
|
@ -1182,6 +1263,10 @@ packages:
|
|||
resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
camelcase@8.0.0:
|
||||
resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==}
|
||||
engines: {node: '>=16'}
|
||||
|
||||
caniuse-lite@1.0.30001695:
|
||||
resolution: {integrity: sha512-vHyLade6wTgI2u1ec3WQBxv+2BrTERV28UXQu9LO6lZ9pYeMk34vjXFLOxo1A4UBA8XTL4njRQZdno/yYaSmWw==}
|
||||
|
||||
|
@ -1200,6 +1285,9 @@ packages:
|
|||
chownr@1.1.4:
|
||||
resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
|
||||
|
||||
class-validator@0.14.1:
|
||||
resolution: {integrity: sha512-2VEG9JICxIqTpoK1eMzZqaV+u/EiwEJkMGzTrZf6sU/fwsnOITVgYJ8yojSy6CaXtO9V0Cc6ZQZ8h8m4UBuLwQ==}
|
||||
|
||||
clsx@2.1.1:
|
||||
resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
|
||||
engines: {node: '>=6'}
|
||||
|
@ -1251,6 +1339,9 @@ packages:
|
|||
engines: {node: '>=4'}
|
||||
hasBin: true
|
||||
|
||||
dayjs@1.11.13:
|
||||
resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==}
|
||||
|
||||
debug@4.4.0:
|
||||
resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==}
|
||||
engines: {node: '>=6.0'}
|
||||
|
@ -1395,6 +1486,9 @@ packages:
|
|||
eastasianwidth@0.2.0:
|
||||
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
||||
|
||||
effect@3.12.10:
|
||||
resolution: {integrity: sha512-fGg3sEN+l1rffWJvXICBTqyyzpa4y1uNo3aI/JLezJDmDk0Qj/WHiy6wVe0cecdr0eFU0XkZcFu2TWpgV8kBiw==}
|
||||
|
||||
electron-to-chromium@1.5.84:
|
||||
resolution: {integrity: sha512-I+DQ8xgafao9Ha6y0qjHHvpZ9OfyA1qKlkHkjywxzniORU2awxyz7f/iVJcULmrF2yrM3nHQf+iDjJtbbexd/g==}
|
||||
|
||||
|
@ -1424,6 +1518,12 @@ packages:
|
|||
peerDependencies:
|
||||
esbuild: '>=0.12 <1'
|
||||
|
||||
esbuild-runner@2.2.2:
|
||||
resolution: {integrity: sha512-fRFVXcmYVmSmtYm2mL8RlUASt2TDkGh3uRcvHFOKNr/T58VrfVeKD9uT9nlgxk96u0LS0ehS/GY7Da/bXWKkhw==}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
esbuild: '*'
|
||||
|
||||
esbuild@0.18.20:
|
||||
resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==}
|
||||
engines: {node: '>=12'}
|
||||
|
@ -1532,6 +1632,10 @@ packages:
|
|||
resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
fast-check@3.23.2:
|
||||
resolution: {integrity: sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
|
||||
fast-deep-equal@3.1.3:
|
||||
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
|
||||
|
||||
|
@ -1593,6 +1697,13 @@ packages:
|
|||
resolution: {integrity: sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==}
|
||||
deprecated: 'Please upgrade to latest, formidable@v2 or formidable@v3! Check these notes: https://bit.ly/2ZEqIau'
|
||||
|
||||
formsnap@2.0.0:
|
||||
resolution: {integrity: sha512-W61elddvdzeBEs10nNvwxQnx/FctJFHBXPk9uluNQAckHo1nuSUvSQGIjtLjTKIbQdQnwEOoxqWrk9tuv0U7hA==}
|
||||
engines: {node: '>=18', pnpm: '>=8.7.0'}
|
||||
peerDependencies:
|
||||
svelte: ^5.0.0
|
||||
sveltekit-superforms: ^2.19.0
|
||||
|
||||
fraction.js@4.3.7:
|
||||
resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
|
||||
|
||||
|
@ -1737,6 +1848,9 @@ packages:
|
|||
resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==}
|
||||
hasBin: true
|
||||
|
||||
joi@17.13.3:
|
||||
resolution: {integrity: sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==}
|
||||
|
||||
js-yaml@4.1.0:
|
||||
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
|
||||
hasBin: true
|
||||
|
@ -1744,6 +1858,10 @@ packages:
|
|||
json-buffer@3.0.1:
|
||||
resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
|
||||
|
||||
json-schema-to-ts@3.1.1:
|
||||
resolution: {integrity: sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==}
|
||||
engines: {node: '>=16'}
|
||||
|
||||
json-schema-traverse@0.4.1:
|
||||
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
|
||||
|
||||
|
@ -1764,6 +1882,9 @@ packages:
|
|||
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
|
||||
libphonenumber-js@1.11.19:
|
||||
resolution: {integrity: sha512-bW/Yp/9dod6fmyR+XqSUL1N5JE7QRxQ3KrBIbYS1FTv32e5i3SEtQVX+71CYNv8maWNSOgnlCoNp9X78f/cKiA==}
|
||||
|
||||
lilconfig@2.1.0:
|
||||
resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==}
|
||||
engines: {node: '>=10'}
|
||||
|
@ -1800,6 +1921,9 @@ packages:
|
|||
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
memoize-weak@1.0.2:
|
||||
resolution: {integrity: sha512-gj39xkrjEw7nCn4nJ1M5ms6+MyMlyiGmttzsqAUsAKn6bYKwuTHh/AO3cKPF8IBrTIYTxb0wWXFs3E//Y8VoWQ==}
|
||||
|
||||
merge2@1.4.1:
|
||||
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
|
||||
engines: {node: '>= 8'}
|
||||
|
@ -1900,6 +2024,10 @@ packages:
|
|||
resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
normalize-url@8.0.1:
|
||||
resolution: {integrity: sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==}
|
||||
engines: {node: '>=14.16'}
|
||||
|
||||
object-assign@4.1.1:
|
||||
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
@ -2108,6 +2236,9 @@ packages:
|
|||
engines: {node: '>=14'}
|
||||
hasBin: true
|
||||
|
||||
property-expr@2.0.6:
|
||||
resolution: {integrity: sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==}
|
||||
|
||||
pump@3.0.2:
|
||||
resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==}
|
||||
|
||||
|
@ -2115,6 +2246,9 @@ packages:
|
|||
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
pure-rand@6.1.0:
|
||||
resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==}
|
||||
|
||||
qs@6.14.0:
|
||||
resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==}
|
||||
engines: {node: '>=0.6'}
|
||||
|
@ -2141,6 +2275,9 @@ packages:
|
|||
resolution: {integrity: sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==}
|
||||
engines: {node: '>= 14.18.0'}
|
||||
|
||||
regenerator-runtime@0.14.1:
|
||||
resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
|
||||
|
||||
resolve-from@4.0.0:
|
||||
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
|
||||
engines: {node: '>=4'}
|
||||
|
@ -2284,6 +2421,10 @@ packages:
|
|||
engines: {node: '>= 7.0.0'}
|
||||
deprecated: Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net
|
||||
|
||||
superstruct@2.0.2:
|
||||
resolution: {integrity: sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
|
||||
supports-color@7.2.0:
|
||||
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
|
||||
engines: {node: '>=8'}
|
||||
|
@ -2325,6 +2466,17 @@ packages:
|
|||
peerDependencies:
|
||||
svelte: ^3.0.0 || ^4.0.0 || ^5.0.0-next.1
|
||||
|
||||
svelte-sonner@0.3.28:
|
||||
resolution: {integrity: sha512-K3AmlySeFifF/cKgsYNv5uXqMVNln0NBAacOYgmkQStLa/UoU0LhfAACU6Gr+YYC8bOCHdVmFNoKuDbMEsppJg==}
|
||||
peerDependencies:
|
||||
svelte: ^3.0.0 || ^4.0.0 || ^5.0.0-next.1
|
||||
|
||||
svelte-toolbelt@0.5.0:
|
||||
resolution: {integrity: sha512-t3tenZcnfQoIeRuQf/jBU7bvTeT3TGkcEE+1EUr5orp0lR7NEpprflpuie3x9Dn0W9nOKqs3HwKGJeeN5Ok1sQ==}
|
||||
engines: {node: '>=18', pnpm: '>=8.7.0'}
|
||||
peerDependencies:
|
||||
svelte: ^5.0.0-next.126
|
||||
|
||||
svelte-toolbelt@0.7.1:
|
||||
resolution: {integrity: sha512-HcBOcR17Vx9bjaOceUvxkY3nGmbBmCBBbuWLLEWO6jtmWH8f/QoWmbyUfQZrpDINH39en1b8mptfPQT9VKQ1xQ==}
|
||||
engines: {node: '>=18', pnpm: '>=8.7.0'}
|
||||
|
@ -2335,6 +2487,15 @@ packages:
|
|||
resolution: {integrity: sha512-H/Vs2O51bwILZbaNUSdr4P1NbLpOGsxl4jJAjd88ELjzRgeRi1BHqexcVGannDr7D1pmTYWWajzHOM7bMbtB9Q==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
sveltekit-superforms@2.23.1:
|
||||
resolution: {integrity: sha512-SPj5ac4SMg8SPyP0Zi3ynwXJa7r9U1CTyn+YSyck67zLsjt367Sro4SZnl3yASrLd5kJ6Y57cgIdYJ2aWNArXw==}
|
||||
peerDependencies:
|
||||
'@sveltejs/kit': 1.x || 2.x
|
||||
svelte: 3.x || 4.x || >=5.0.0-next.51
|
||||
|
||||
tabbable@6.2.0:
|
||||
resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==}
|
||||
|
||||
tailwind-merge@2.5.4:
|
||||
resolution: {integrity: sha512-0q8cfZHMu9nuYP/b5Shb7Y7Sh1B7Nnl5GqNr1U+n2p6+mybvRtayrQ+0042Z5byvTA8ihjlP8Odo8/VnHbZu4Q==}
|
||||
|
||||
|
@ -2371,23 +2532,39 @@ packages:
|
|||
thenify@3.3.1:
|
||||
resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
|
||||
|
||||
tiny-case@1.0.3:
|
||||
resolution: {integrity: sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==}
|
||||
|
||||
to-regex-range@5.0.1:
|
||||
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
|
||||
engines: {node: '>=8.0'}
|
||||
|
||||
toposort@2.0.2:
|
||||
resolution: {integrity: sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==}
|
||||
|
||||
totalist@3.0.1:
|
||||
resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
ts-algebra@2.0.0:
|
||||
resolution: {integrity: sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==}
|
||||
|
||||
ts-api-utils@2.0.0:
|
||||
resolution: {integrity: sha512-xCt/TOAc+EOHS1XPnijD3/yzpH6qg2xppZO1YDqGoVsNXfQfzHpOdNuXwrwOU8u4ITXJyDCTyt8w5g1sZv9ynQ==}
|
||||
engines: {node: '>=18.12'}
|
||||
peerDependencies:
|
||||
typescript: '>=4.8.4'
|
||||
|
||||
ts-deepmerge@7.0.2:
|
||||
resolution: {integrity: sha512-akcpDTPuez4xzULo5NwuoKwYRtjQJ9eoNfBACiBMaXwNAx7B1PKfe5wqUFJuW5uKzQ68YjDFwPaWHDG1KnFGsA==}
|
||||
engines: {node: '>=14.13.1'}
|
||||
|
||||
ts-interface-checker@0.1.13:
|
||||
resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
|
||||
|
||||
tslib@2.4.0:
|
||||
resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==}
|
||||
|
||||
tslib@2.8.1:
|
||||
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
|
||||
|
||||
|
@ -2398,6 +2575,10 @@ packages:
|
|||
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
|
||||
type-fest@2.19.0:
|
||||
resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==}
|
||||
engines: {node: '>=12.20'}
|
||||
|
||||
typescript-eslint@8.22.0:
|
||||
resolution: {integrity: sha512-Y2rj210FW1Wb6TWXzQc5+P+EWI9/zdS57hLEc0gnyuvdzWo8+Y8brKlbj0muejonhMI/xAZCnZZwjbIfv1CkOw==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
@ -2425,6 +2606,21 @@ packages:
|
|||
util-deprecate@1.0.2:
|
||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||
|
||||
valibot@0.31.1:
|
||||
resolution: {integrity: sha512-2YYIhPrnVSz/gfT2/iXVTrSj92HwchCt9Cga/6hX4B26iCz9zkIsGTS0HjDYTZfTi1Un0X6aRvhBi1cfqs/i0Q==}
|
||||
|
||||
valibot@1.0.0-beta.11:
|
||||
resolution: {integrity: sha512-Ztl5Iks1Ql7Z6CwkS5oyqguN3G8tmUiNlsHpqbDt6DLMpm+eu+n8Q7f921gI3uHvNZ8xDVkd4cEJP5t+lELOfw==}
|
||||
peerDependencies:
|
||||
typescript: '>=5'
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
validator@13.12.0:
|
||||
resolution: {integrity: sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==}
|
||||
engines: {node: '>= 0.10'}
|
||||
|
||||
vite-imagetools@7.0.5:
|
||||
resolution: {integrity: sha512-OOvVnaBTqJJ2J7X1cM1qpH4pj9jsfTxia1VSuWeyXtf+OnP8d0YI1LHpv8y2NT47wg+n7XiTgh3BvcSffuBWrw==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
|
@ -2510,9 +2706,20 @@ packages:
|
|||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
yup@1.6.1:
|
||||
resolution: {integrity: sha512-JED8pB50qbA4FOkDol0bYF/p60qSEDQqBD0/qeIrUCG1KbPBIQ776fCUNb9ldbPcSTxA69g/47XTo4TqWiuXOA==}
|
||||
|
||||
zimmerframe@1.1.2:
|
||||
resolution: {integrity: sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==}
|
||||
|
||||
zod-to-json-schema@3.24.1:
|
||||
resolution: {integrity: sha512-3h08nf3Vw3Wl3PK+q3ow/lIil81IT2Oa7YpQyUUDsEWbXveMesdfK1xBd2RhCkynwZndAxixji/7SYJJowr62w==}
|
||||
peerDependencies:
|
||||
zod: ^3.24.1
|
||||
|
||||
zod@3.24.1:
|
||||
resolution: {integrity: sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==}
|
||||
|
||||
snapshots:
|
||||
|
||||
'@alloc/quick-lru@5.2.0': {}
|
||||
|
@ -2522,6 +2729,19 @@ snapshots:
|
|||
'@jridgewell/gen-mapping': 0.3.8
|
||||
'@jridgewell/trace-mapping': 0.3.25
|
||||
|
||||
'@ark/schema@0.39.0':
|
||||
dependencies:
|
||||
'@ark/util': 0.39.0
|
||||
optional: true
|
||||
|
||||
'@ark/util@0.39.0':
|
||||
optional: true
|
||||
|
||||
'@babel/runtime@7.26.7':
|
||||
dependencies:
|
||||
regenerator-runtime: 0.14.1
|
||||
optional: true
|
||||
|
||||
'@drizzle-team/brocli@0.10.2': {}
|
||||
|
||||
'@emnapi/runtime@1.3.1':
|
||||
|
@ -2795,6 +3015,9 @@ snapshots:
|
|||
'@eslint/core': 0.10.0
|
||||
levn: 0.4.1
|
||||
|
||||
'@exodus/schemasafe@1.3.0':
|
||||
optional: true
|
||||
|
||||
'@floating-ui/core@1.6.9':
|
||||
dependencies:
|
||||
'@floating-ui/utils': 0.2.9
|
||||
|
@ -2810,6 +3033,23 @@ snapshots:
|
|||
|
||||
'@fontsource-variable/smooch-sans@5.1.1': {}
|
||||
|
||||
'@gcornut/valibot-json-schema@0.31.0':
|
||||
dependencies:
|
||||
valibot: 0.31.1
|
||||
optionalDependencies:
|
||||
'@types/json-schema': 7.0.15
|
||||
esbuild: 0.24.2
|
||||
esbuild-runner: 2.2.2(esbuild@0.24.2)
|
||||
optional: true
|
||||
|
||||
'@hapi/hoek@9.3.0':
|
||||
optional: true
|
||||
|
||||
'@hapi/topo@5.1.0':
|
||||
dependencies:
|
||||
'@hapi/hoek': 9.3.0
|
||||
optional: true
|
||||
|
||||
'@humanfs/core@0.19.1': {}
|
||||
|
||||
'@humanfs/node@0.16.6':
|
||||
|
@ -2947,6 +3187,9 @@ snapshots:
|
|||
|
||||
'@polka/url@1.0.0-next.28': {}
|
||||
|
||||
'@poppinss/macroable@1.0.4':
|
||||
optional: true
|
||||
|
||||
'@rollup/plugin-commonjs@28.0.2(rollup@4.31.0)':
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 5.1.4(rollup@4.31.0)
|
||||
|
@ -3040,6 +3283,20 @@ snapshots:
|
|||
'@rollup/rollup-win32-x64-msvc@4.31.0':
|
||||
optional: true
|
||||
|
||||
'@sideway/address@4.1.5':
|
||||
dependencies:
|
||||
'@hapi/hoek': 9.3.0
|
||||
optional: true
|
||||
|
||||
'@sideway/formula@3.0.1':
|
||||
optional: true
|
||||
|
||||
'@sideway/pinpoint@2.0.0':
|
||||
optional: true
|
||||
|
||||
'@sinclair/typebox@0.34.16':
|
||||
optional: true
|
||||
|
||||
'@sveltejs/adapter-node@5.2.12(@sveltejs/kit@2.16.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.1)(vite@6.0.11(@types/node@22.13.1)(jiti@1.21.7)(yaml@2.7.0)))(svelte@5.19.1)(vite@6.0.11(@types/node@22.13.1)(jiti@1.21.7)(yaml@2.7.0)))':
|
||||
dependencies:
|
||||
'@rollup/plugin-commonjs': 28.0.2(rollup@4.31.0)
|
||||
|
@ -3134,6 +3391,23 @@ snapshots:
|
|||
dependencies:
|
||||
'@types/spotify-api': 0.0.25
|
||||
|
||||
'@types/validator@13.12.2':
|
||||
optional: true
|
||||
|
||||
'@typeschema/class-validator@0.3.0(@types/json-schema@7.0.15)(class-validator@0.14.1)':
|
||||
dependencies:
|
||||
'@typeschema/core': 0.14.0(@types/json-schema@7.0.15)
|
||||
optionalDependencies:
|
||||
class-validator: 0.14.1
|
||||
transitivePeerDependencies:
|
||||
- '@types/json-schema'
|
||||
optional: true
|
||||
|
||||
'@typeschema/core@0.14.0(@types/json-schema@7.0.15)':
|
||||
optionalDependencies:
|
||||
'@types/json-schema': 7.0.15
|
||||
optional: true
|
||||
|
||||
'@typescript-eslint/eslint-plugin@8.22.0(@typescript-eslint/parser@8.22.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3)':
|
||||
dependencies:
|
||||
'@eslint-community/regexpp': 4.12.1
|
||||
|
@ -3211,6 +3485,21 @@ snapshots:
|
|||
'@typescript-eslint/types': 8.22.0
|
||||
eslint-visitor-keys: 4.2.0
|
||||
|
||||
'@vinejs/compiler@3.0.0':
|
||||
optional: true
|
||||
|
||||
'@vinejs/vine@3.0.0':
|
||||
dependencies:
|
||||
'@poppinss/macroable': 1.0.4
|
||||
'@types/validator': 13.12.2
|
||||
'@vinejs/compiler': 3.0.0
|
||||
camelcase: 8.0.0
|
||||
dayjs: 1.11.13
|
||||
dlv: 1.1.3
|
||||
normalize-url: 8.0.1
|
||||
validator: 13.12.0
|
||||
optional: true
|
||||
|
||||
acorn-jsx@5.3.2(acorn@8.14.0):
|
||||
dependencies:
|
||||
acorn: 8.14.0
|
||||
|
@ -3251,6 +3540,12 @@ snapshots:
|
|||
|
||||
aria-query@5.3.2: {}
|
||||
|
||||
arktype@2.0.4:
|
||||
dependencies:
|
||||
'@ark/schema': 0.39.0
|
||||
'@ark/util': 0.39.0
|
||||
optional: true
|
||||
|
||||
asynckit@0.4.0: {}
|
||||
|
||||
autoprefixer@10.4.20(postcss@8.5.1):
|
||||
|
@ -3280,7 +3575,7 @@ snapshots:
|
|||
dependencies:
|
||||
file-uri-to-path: 1.0.0
|
||||
|
||||
bits-ui@1.0.0-next.86(svelte@5.19.1):
|
||||
bits-ui@1.0.0-next.94(svelte@5.19.1):
|
||||
dependencies:
|
||||
'@floating-ui/core': 1.6.9
|
||||
'@floating-ui/dom': 1.6.13
|
||||
|
@ -3289,6 +3584,7 @@ snapshots:
|
|||
runed: 0.23.2(svelte@5.19.1)
|
||||
svelte: 5.19.1
|
||||
svelte-toolbelt: 0.7.1(svelte@5.19.1)
|
||||
tabbable: 6.2.0
|
||||
|
||||
bl@4.1.0:
|
||||
dependencies:
|
||||
|
@ -3337,6 +3633,9 @@ snapshots:
|
|||
|
||||
camelcase-css@2.0.1: {}
|
||||
|
||||
camelcase@8.0.0:
|
||||
optional: true
|
||||
|
||||
caniuse-lite@1.0.30001695: {}
|
||||
|
||||
chalk@4.1.2:
|
||||
|
@ -3362,6 +3661,13 @@ snapshots:
|
|||
|
||||
chownr@1.1.4: {}
|
||||
|
||||
class-validator@0.14.1:
|
||||
dependencies:
|
||||
'@types/validator': 13.12.2
|
||||
libphonenumber-js: 1.11.19
|
||||
validator: 13.12.0
|
||||
optional: true
|
||||
|
||||
clsx@2.1.1: {}
|
||||
|
||||
color-convert@2.0.1:
|
||||
|
@ -3404,6 +3710,9 @@ snapshots:
|
|||
|
||||
cssesc@3.0.0: {}
|
||||
|
||||
dayjs@1.11.13:
|
||||
optional: true
|
||||
|
||||
debug@4.4.0:
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
|
@ -3450,6 +3759,11 @@ snapshots:
|
|||
|
||||
eastasianwidth@0.2.0: {}
|
||||
|
||||
effect@3.12.10:
|
||||
dependencies:
|
||||
fast-check: 3.23.2
|
||||
optional: true
|
||||
|
||||
electron-to-chromium@1.5.84: {}
|
||||
|
||||
emoji-regex@8.0.0: {}
|
||||
|
@ -3475,6 +3789,13 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
esbuild-runner@2.2.2(esbuild@0.24.2):
|
||||
dependencies:
|
||||
esbuild: 0.24.2
|
||||
source-map-support: 0.5.21
|
||||
tslib: 2.4.0
|
||||
optional: true
|
||||
|
||||
esbuild@0.18.20:
|
||||
optionalDependencies:
|
||||
'@esbuild/android-arm': 0.18.20
|
||||
|
@ -3675,6 +3996,11 @@ snapshots:
|
|||
|
||||
expand-template@2.0.3: {}
|
||||
|
||||
fast-check@3.23.2:
|
||||
dependencies:
|
||||
pure-rand: 6.1.0
|
||||
optional: true
|
||||
|
||||
fast-deep-equal@3.1.3: {}
|
||||
|
||||
fast-glob@3.3.3:
|
||||
|
@ -3734,6 +4060,12 @@ snapshots:
|
|||
|
||||
formidable@1.2.6: {}
|
||||
|
||||
formsnap@2.0.0(svelte@5.19.1)(sveltekit-superforms@2.23.1(@sveltejs/kit@2.16.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.1)(vite@6.0.11(@types/node@22.13.1)(jiti@1.21.7)(yaml@2.7.0)))(svelte@5.19.1)(vite@6.0.11(@types/node@22.13.1)(jiti@1.21.7)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.19.1)(typescript@5.7.3)):
|
||||
dependencies:
|
||||
svelte: 5.19.1
|
||||
svelte-toolbelt: 0.5.0(svelte@5.19.1)
|
||||
sveltekit-superforms: 2.23.1(@sveltejs/kit@2.16.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.1)(vite@6.0.11(@types/node@22.13.1)(jiti@1.21.7)(yaml@2.7.0)))(svelte@5.19.1)(vite@6.0.11(@types/node@22.13.1)(jiti@1.21.7)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.19.1)(typescript@5.7.3)
|
||||
|
||||
fraction.js@4.3.7: {}
|
||||
|
||||
fs-constants@1.0.0: {}
|
||||
|
@ -3861,12 +4193,27 @@ snapshots:
|
|||
|
||||
jiti@1.21.7: {}
|
||||
|
||||
joi@17.13.3:
|
||||
dependencies:
|
||||
'@hapi/hoek': 9.3.0
|
||||
'@hapi/topo': 5.1.0
|
||||
'@sideway/address': 4.1.5
|
||||
'@sideway/formula': 3.0.1
|
||||
'@sideway/pinpoint': 2.0.0
|
||||
optional: true
|
||||
|
||||
js-yaml@4.1.0:
|
||||
dependencies:
|
||||
argparse: 2.0.1
|
||||
|
||||
json-buffer@3.0.1: {}
|
||||
|
||||
json-schema-to-ts@3.1.1:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.26.7
|
||||
ts-algebra: 2.0.0
|
||||
optional: true
|
||||
|
||||
json-schema-traverse@0.4.1: {}
|
||||
|
||||
json-stable-stringify-without-jsonify@1.0.1: {}
|
||||
|
@ -3884,6 +4231,9 @@ snapshots:
|
|||
prelude-ls: 1.2.1
|
||||
type-check: 0.4.0
|
||||
|
||||
libphonenumber-js@1.11.19:
|
||||
optional: true
|
||||
|
||||
lilconfig@2.1.0: {}
|
||||
|
||||
lilconfig@3.1.3: {}
|
||||
|
@ -3910,6 +4260,8 @@ snapshots:
|
|||
|
||||
math-intrinsics@1.1.0: {}
|
||||
|
||||
memoize-weak@1.0.2: {}
|
||||
|
||||
merge2@1.4.1: {}
|
||||
|
||||
methods@1.1.2: {}
|
||||
|
@ -3979,6 +4331,9 @@ snapshots:
|
|||
|
||||
normalize-range@0.1.2: {}
|
||||
|
||||
normalize-url@8.0.1:
|
||||
optional: true
|
||||
|
||||
object-assign@4.1.1: {}
|
||||
|
||||
object-hash@3.0.0: {}
|
||||
|
@ -4115,6 +4470,9 @@ snapshots:
|
|||
|
||||
prettier@3.4.2: {}
|
||||
|
||||
property-expr@2.0.6:
|
||||
optional: true
|
||||
|
||||
pump@3.0.2:
|
||||
dependencies:
|
||||
end-of-stream: 1.4.4
|
||||
|
@ -4122,6 +4480,9 @@ snapshots:
|
|||
|
||||
punycode@2.3.1: {}
|
||||
|
||||
pure-rand@6.1.0:
|
||||
optional: true
|
||||
|
||||
qs@6.14.0:
|
||||
dependencies:
|
||||
side-channel: 1.1.0
|
||||
|
@ -4151,6 +4512,9 @@ snapshots:
|
|||
|
||||
readdirp@4.1.1: {}
|
||||
|
||||
regenerator-runtime@0.14.1:
|
||||
optional: true
|
||||
|
||||
resolve-from@4.0.0: {}
|
||||
|
||||
resolve-pkg-maps@1.0.0: {}
|
||||
|
@ -4360,6 +4724,9 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
superstruct@2.0.2:
|
||||
optional: true
|
||||
|
||||
supports-color@7.2.0:
|
||||
dependencies:
|
||||
has-flag: 4.0.0
|
||||
|
@ -4402,6 +4769,16 @@ snapshots:
|
|||
dependencies:
|
||||
svelte: 5.19.1
|
||||
|
||||
svelte-sonner@0.3.28(svelte@5.19.1):
|
||||
dependencies:
|
||||
svelte: 5.19.1
|
||||
|
||||
svelte-toolbelt@0.5.0(svelte@5.19.1):
|
||||
dependencies:
|
||||
clsx: 2.1.1
|
||||
style-to-object: 1.0.8
|
||||
svelte: 5.19.1
|
||||
|
||||
svelte-toolbelt@0.7.1(svelte@5.19.1):
|
||||
dependencies:
|
||||
clsx: 2.1.1
|
||||
|
@ -4426,6 +4803,35 @@ snapshots:
|
|||
magic-string: 0.30.17
|
||||
zimmerframe: 1.1.2
|
||||
|
||||
sveltekit-superforms@2.23.1(@sveltejs/kit@2.16.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.1)(vite@6.0.11(@types/node@22.13.1)(jiti@1.21.7)(yaml@2.7.0)))(svelte@5.19.1)(vite@6.0.11(@types/node@22.13.1)(jiti@1.21.7)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.19.1)(typescript@5.7.3):
|
||||
dependencies:
|
||||
'@sveltejs/kit': 2.16.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.1)(vite@6.0.11(@types/node@22.13.1)(jiti@1.21.7)(yaml@2.7.0)))(svelte@5.19.1)(vite@6.0.11(@types/node@22.13.1)(jiti@1.21.7)(yaml@2.7.0))
|
||||
devalue: 5.1.1
|
||||
memoize-weak: 1.0.2
|
||||
svelte: 5.19.1
|
||||
ts-deepmerge: 7.0.2
|
||||
optionalDependencies:
|
||||
'@exodus/schemasafe': 1.3.0
|
||||
'@gcornut/valibot-json-schema': 0.31.0
|
||||
'@sinclair/typebox': 0.34.16
|
||||
'@typeschema/class-validator': 0.3.0(@types/json-schema@7.0.15)(class-validator@0.14.1)
|
||||
'@vinejs/vine': 3.0.0
|
||||
arktype: 2.0.4
|
||||
class-validator: 0.14.1
|
||||
effect: 3.12.10
|
||||
joi: 17.13.3
|
||||
json-schema-to-ts: 3.1.1
|
||||
superstruct: 2.0.2
|
||||
valibot: 1.0.0-beta.11(typescript@5.7.3)
|
||||
yup: 1.6.1
|
||||
zod: 3.24.1
|
||||
zod-to-json-schema: 3.24.1(zod@3.24.1)
|
||||
transitivePeerDependencies:
|
||||
- '@types/json-schema'
|
||||
- typescript
|
||||
|
||||
tabbable@6.2.0: {}
|
||||
|
||||
tailwind-merge@2.5.4: {}
|
||||
|
||||
tailwind-merge@2.6.0: {}
|
||||
|
@ -4489,18 +4895,32 @@ snapshots:
|
|||
dependencies:
|
||||
any-promise: 1.3.0
|
||||
|
||||
tiny-case@1.0.3:
|
||||
optional: true
|
||||
|
||||
to-regex-range@5.0.1:
|
||||
dependencies:
|
||||
is-number: 7.0.0
|
||||
|
||||
toposort@2.0.2:
|
||||
optional: true
|
||||
|
||||
totalist@3.0.1: {}
|
||||
|
||||
ts-algebra@2.0.0:
|
||||
optional: true
|
||||
|
||||
ts-api-utils@2.0.0(typescript@5.7.3):
|
||||
dependencies:
|
||||
typescript: 5.7.3
|
||||
|
||||
ts-deepmerge@7.0.2: {}
|
||||
|
||||
ts-interface-checker@0.1.13: {}
|
||||
|
||||
tslib@2.4.0:
|
||||
optional: true
|
||||
|
||||
tslib@2.8.1: {}
|
||||
|
||||
tunnel-agent@0.6.0:
|
||||
|
@ -4511,6 +4931,9 @@ snapshots:
|
|||
dependencies:
|
||||
prelude-ls: 1.2.1
|
||||
|
||||
type-fest@2.19.0:
|
||||
optional: true
|
||||
|
||||
typescript-eslint@8.22.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3):
|
||||
dependencies:
|
||||
'@typescript-eslint/eslint-plugin': 8.22.0(@typescript-eslint/parser@8.22.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3)
|
||||
|
@ -4537,6 +4960,17 @@ snapshots:
|
|||
|
||||
util-deprecate@1.0.2: {}
|
||||
|
||||
valibot@0.31.1:
|
||||
optional: true
|
||||
|
||||
valibot@1.0.0-beta.11(typescript@5.7.3):
|
||||
optionalDependencies:
|
||||
typescript: 5.7.3
|
||||
optional: true
|
||||
|
||||
validator@13.12.0:
|
||||
optional: true
|
||||
|
||||
vite-imagetools@7.0.5(rollup@4.31.0):
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 5.1.4(rollup@4.31.0)
|
||||
|
@ -4586,4 +5020,19 @@ snapshots:
|
|||
|
||||
yocto-queue@0.1.0: {}
|
||||
|
||||
yup@1.6.1:
|
||||
dependencies:
|
||||
property-expr: 2.0.6
|
||||
tiny-case: 1.0.3
|
||||
toposort: 2.0.2
|
||||
type-fest: 2.19.0
|
||||
optional: true
|
||||
|
||||
zimmerframe@1.1.2: {}
|
||||
|
||||
zod-to-json-schema@3.24.1(zod@3.24.1):
|
||||
dependencies:
|
||||
zod: 3.24.1
|
||||
optional: true
|
||||
|
||||
zod@3.24.1: {}
|
||||
|
|
|
@ -1,6 +1,25 @@
|
|||
import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core';
|
||||
import { relations } from 'drizzle-orm/relations';
|
||||
import { sqliteTable, text } from 'drizzle-orm/sqlite-core';
|
||||
import { nanoid } from 'nanoid';
|
||||
|
||||
export const user = sqliteTable('user', {
|
||||
id: integer('id').primaryKey(),
|
||||
age: integer('age')
|
||||
export const questions = sqliteTable('questions', {
|
||||
id: text('id')
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
creator: text('creator').notNull(), // session token
|
||||
content: text('content').notNull().unique()
|
||||
});
|
||||
|
||||
export const answers = sqliteTable('answers', {
|
||||
id: text('id')
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
creator: text('creator').notNull(), // session token
|
||||
content: text('content').notNull(),
|
||||
questionId: text('question_id').references(() => questions.id)
|
||||
});
|
||||
|
||||
// Relations
|
||||
export const questionsRelations = relations(questions, ({ many }) => ({
|
||||
answers: many(answers)
|
||||
}));
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import type { Picture } from 'vite-imagetools';
|
||||
import type { answers, questions } from './server/db/schema';
|
||||
|
||||
export type EnhancedImage = {
|
||||
src: string | Picture;
|
||||
|
@ -75,3 +76,6 @@ export type Tag = {
|
|||
};
|
||||
|
||||
export type TagsObj = Record<string, Tag>;
|
||||
|
||||
export type Answer = typeof answers.$inferSelect;
|
||||
export type Question = typeof questions.$inferSelect & { answers: Answer[] };
|
||||
|
|
72
src/routes/api/rahvatarkus/answer/+server.ts
Normal file
72
src/routes/api/rahvatarkus/answer/+server.ts
Normal file
|
@ -0,0 +1,72 @@
|
|||
import { json } from '@sveltejs/kit';
|
||||
import { db } from '$lib/server/db';
|
||||
import { questions, answers } from '$lib/server/db/schema';
|
||||
import { eq } from 'drizzle-orm';
|
||||
|
||||
const maxAnswers = 5;
|
||||
|
||||
export async function POST({ locals, request }) {
|
||||
const { userId, questionId, content }: { userId: string; questionId: string; content: string } =
|
||||
await request.json();
|
||||
const { session } = locals;
|
||||
|
||||
if (!session?.data?.userId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const user = session.data.userId;
|
||||
|
||||
if (!user || !userId || user !== userId) {
|
||||
return json({ error: 'Unauthorized' }, { status: 401 });
|
||||
}
|
||||
|
||||
if (!content) {
|
||||
return json({ error: 'Answer is required' }, { status: 400 });
|
||||
}
|
||||
|
||||
if (!questionId) {
|
||||
return json({ error: 'No question specified' }, { status: 400 });
|
||||
}
|
||||
|
||||
const question = await db
|
||||
.select({
|
||||
question: questions
|
||||
})
|
||||
.from(questions)
|
||||
.where(eq(questions.id, questionId))
|
||||
.limit(1);
|
||||
|
||||
if (!question) {
|
||||
return json({ error: 'Question not found' }, { status: 400 });
|
||||
}
|
||||
|
||||
if (question[0].question.creator === user) {
|
||||
return json({ error: 'Not allowed to answer your own question' }, { status: 400 });
|
||||
}
|
||||
|
||||
const currentAnswers = await db
|
||||
.select({
|
||||
answer: answers
|
||||
})
|
||||
.from(answers)
|
||||
.where(eq(answers.questionId, questionId));
|
||||
|
||||
if (currentAnswers.length >= maxAnswers) {
|
||||
return json({ error: 'No more answers needed for this question' }, { status: 400 });
|
||||
}
|
||||
|
||||
try {
|
||||
const [newAnswer] = await db
|
||||
.insert(answers)
|
||||
.values({
|
||||
content: content,
|
||||
creator: userId,
|
||||
questionId: questionId
|
||||
})
|
||||
.returning();
|
||||
|
||||
return json(newAnswer);
|
||||
} catch (e) {
|
||||
return json({ error: e }, { status: 400 });
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
import { json } from '@sveltejs/kit';
|
||||
import { db } from '$lib/server/db';
|
||||
import { questions, answers } from '$lib/server/db/schema';
|
||||
import { eq, sql } from 'drizzle-orm';
|
||||
import type { Question } from '$lib/types';
|
||||
|
||||
export async function GET({ params }) {
|
||||
const limit = parseInt(params.limit) || 10;
|
||||
const offset = parseInt(params.offset) || 0;
|
||||
|
||||
// Get total count
|
||||
const [{ total }] = await db
|
||||
.select({
|
||||
total: sql`count(DISTINCT ${questions.id})`
|
||||
})
|
||||
.from(questions)
|
||||
.innerJoin(answers, eq(questions.id, answers.questionId));
|
||||
|
||||
const results = await db
|
||||
.select({
|
||||
question: questions,
|
||||
answers: answers
|
||||
})
|
||||
.from(questions)
|
||||
.innerJoin(answers, eq(questions.id, answers.questionId))
|
||||
.limit(limit)
|
||||
.offset(offset);
|
||||
|
||||
// Group answers by question
|
||||
type QuestionMap = {
|
||||
[key: string]: Question;
|
||||
};
|
||||
|
||||
const questionsWithAnswers = results.reduce<QuestionMap>((acc, row) => {
|
||||
const questionId = row.question.id;
|
||||
|
||||
if (!acc[questionId]) {
|
||||
acc[questionId] = {
|
||||
...row.question,
|
||||
answers: []
|
||||
};
|
||||
}
|
||||
|
||||
if (row.answers) {
|
||||
acc[questionId].answers.push(row.answers);
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
return json({ data: Object.values(questionsWithAnswers), meta: { limit, offset, total } });
|
||||
}
|
67
src/routes/api/rahvatarkus/question/+server.ts
Normal file
67
src/routes/api/rahvatarkus/question/+server.ts
Normal file
|
@ -0,0 +1,67 @@
|
|||
import { json } from '@sveltejs/kit';
|
||||
import { db } from '$lib/server/db';
|
||||
import { questions, answers } from '$lib/server/db/schema';
|
||||
import { eq, count, and, not, sql } from 'drizzle-orm';
|
||||
|
||||
export async function GET({ locals }) {
|
||||
const { session } = locals;
|
||||
|
||||
if (!session?.data?.userId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const user = session.data.userId;
|
||||
|
||||
const questionWithAnswerCount = await db
|
||||
.select({
|
||||
id: questions.id,
|
||||
content: questions.content,
|
||||
answerCount: count(answers.id)
|
||||
})
|
||||
.from(questions)
|
||||
.leftJoin(answers, eq(questions.id, answers.questionId))
|
||||
.groupBy(questions.id)
|
||||
.having(and(sql`${count(answers.id)} < 5`, not(eq(questions.creator, user))))
|
||||
.orderBy(sql`RANDOM()`)
|
||||
.limit(1);
|
||||
|
||||
if (!questionWithAnswerCount.length) {
|
||||
return json({ error: 'No questions available' }, { status: 404 });
|
||||
}
|
||||
|
||||
return json(questionWithAnswerCount[0]);
|
||||
}
|
||||
|
||||
export async function POST({ locals, request }) {
|
||||
const { userId, content }: { userId: string; content: string } = await request.json();
|
||||
const { session } = locals;
|
||||
|
||||
if (!session?.data?.userId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const user = session.data.userId;
|
||||
|
||||
if (!user || !userId || user !== userId) {
|
||||
console.log(user, userId);
|
||||
return json({ error: 'Unauthorized' }, { status: 401 });
|
||||
}
|
||||
|
||||
if (!content) {
|
||||
return json({ error: 'Content is required' }, { status: 400 });
|
||||
}
|
||||
|
||||
try {
|
||||
const [newQuestion] = await db
|
||||
.insert(questions)
|
||||
.values({
|
||||
content: content.at(-1) === '?' ? content.slice(0, -1) : content,
|
||||
creator: userId
|
||||
})
|
||||
.returning();
|
||||
|
||||
return json(newQuestion);
|
||||
} catch (e) {
|
||||
return json({ error: e }, { status: 400 });
|
||||
}
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
<script lang="ts">
|
||||
import { baseURL, stuffSite } from '$lib/config.js';
|
||||
|
||||
import { Toaster } from '$lib/components/ui/sonner/index.js';
|
||||
|
||||
let { children, data } = $props();
|
||||
|
||||
const title = data?.name ? `${data.name} | ${stuffSite.name}` : stuffSite.name;
|
||||
|
@ -18,6 +20,8 @@
|
|||
<meta property="og:image" content={baseURL + ogImage} />
|
||||
</svelte:head>
|
||||
|
||||
<Toaster />
|
||||
|
||||
{@render children()}
|
||||
|
||||
{#if data?.name === 'Vau kui vali'}
|
||||
|
|
162
src/routes/vinge/rahvatarkus/+page.server.ts
Normal file
162
src/routes/vinge/rahvatarkus/+page.server.ts
Normal file
|
@ -0,0 +1,162 @@
|
|||
import type { Actions, PageServerLoad } from './$types';
|
||||
import type { Question } from '$lib/types';
|
||||
import { formSchema as questionSchema } from './question-schema';
|
||||
import { formSchema as answerSchema } from './answer-schema';
|
||||
|
||||
import { superValidate } from 'sveltekit-superforms';
|
||||
import { zod } from 'sveltekit-superforms/adapters';
|
||||
import { nanoid } from 'nanoid';
|
||||
import { fail } from '@sveltejs/kit';
|
||||
|
||||
const perPage = 5;
|
||||
|
||||
export const load: PageServerLoad = async ({ fetch, locals }) => {
|
||||
const { session } = locals;
|
||||
|
||||
if (!session?.data?.userId) {
|
||||
await session.setData({ userId: nanoid() });
|
||||
await session.save();
|
||||
}
|
||||
|
||||
const user = session.data.userId;
|
||||
|
||||
const res = await fetch('/api/rahvatarkus/question')
|
||||
.then(async (res) => {
|
||||
const data = await res.json();
|
||||
return { ok: res.ok, data: data };
|
||||
})
|
||||
.then((data) => {
|
||||
return data;
|
||||
});
|
||||
|
||||
let question: Question | undefined = undefined;
|
||||
|
||||
if (res.ok) {
|
||||
question = res.data;
|
||||
}
|
||||
|
||||
const archiveRes = fetch(`/api/rahvatarkus/archive/${perPage}`)
|
||||
.then((res) => {
|
||||
return res.json();
|
||||
})
|
||||
.then((data) => {
|
||||
return data;
|
||||
});
|
||||
|
||||
return {
|
||||
user: user,
|
||||
question: question,
|
||||
question_form: await superValidate(zod(questionSchema)),
|
||||
answer_form: await superValidate({ questionId: question?.id }, zod(answerSchema), {
|
||||
errors: false
|
||||
}),
|
||||
perPage,
|
||||
streamed: {
|
||||
archive: archiveRes
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export const actions: Actions = {
|
||||
answer: async (event) => {
|
||||
const { session } = event.locals;
|
||||
if (!session?.data?.userId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const user = session.data.userId;
|
||||
|
||||
const form = await superValidate(event, zod(answerSchema));
|
||||
|
||||
if (!form.valid) {
|
||||
return fail(400, {
|
||||
form
|
||||
});
|
||||
}
|
||||
|
||||
const response = await event
|
||||
.fetch('/api/rahvatarkus/answer', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
userId: user,
|
||||
content: form.data.answer,
|
||||
questionId: form.data.questionId
|
||||
})
|
||||
})
|
||||
.then(async (res) => {
|
||||
const data = await res.json();
|
||||
return { ok: res.ok, data: data };
|
||||
})
|
||||
.then((data) => {
|
||||
return data;
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorMessage = response.data?.error;
|
||||
|
||||
if (form.errors.answer) {
|
||||
form.errors.answer.push(errorMessage);
|
||||
} else {
|
||||
form.errors.answer = [errorMessage];
|
||||
}
|
||||
|
||||
return fail(400, {
|
||||
form
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
form
|
||||
};
|
||||
},
|
||||
|
||||
question: async (event) => {
|
||||
const { session } = event.locals;
|
||||
if (!session?.data?.userId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const user = session.data.userId;
|
||||
|
||||
const form = await superValidate(event, zod(questionSchema));
|
||||
|
||||
if (!form.valid) {
|
||||
return fail(400, {
|
||||
form
|
||||
});
|
||||
}
|
||||
|
||||
const response = await event
|
||||
.fetch('/api/rahvatarkus/question', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ userId: user, content: form.data.question })
|
||||
})
|
||||
.then(async (res) => {
|
||||
const data = await res.json();
|
||||
return { ok: res.ok, data: data };
|
||||
})
|
||||
.then((data) => {
|
||||
return data;
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
if (response.data?.error?.code === 'SQLITE_CONSTRAINT_UNIQUE') {
|
||||
const errorMessage = 'Sellel küsimusel on juba vastus.';
|
||||
|
||||
if (form.errors.question) {
|
||||
form.errors.question.push(errorMessage);
|
||||
} else {
|
||||
form.errors.question = [errorMessage];
|
||||
}
|
||||
}
|
||||
|
||||
return fail(400, {
|
||||
form
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
form
|
||||
};
|
||||
}
|
||||
};
|
63
src/routes/vinge/rahvatarkus/+page.svelte
Normal file
63
src/routes/vinge/rahvatarkus/+page.svelte
Normal file
|
@ -0,0 +1,63 @@
|
|||
<script lang="ts">
|
||||
import type { PageData } from './$types.js';
|
||||
|
||||
import * as Accordion from '$lib/components/ui/accordion/index.js';
|
||||
import * as Pagination from '$lib/components/ui/pagination/index.js';
|
||||
|
||||
import QuestionForm from './question-form.svelte';
|
||||
import AnswerForm from './answer-form.svelte';
|
||||
import SuperDebug from 'sveltekit-superforms';
|
||||
|
||||
let { data }: { data: PageData } = $props();
|
||||
|
||||
$inspect(data);
|
||||
</script>
|
||||
|
||||
<QuestionForm {data} />
|
||||
<AnswerForm {data} />
|
||||
|
||||
{#await data.streamed.archive}
|
||||
<p>loading</p>
|
||||
{:then archive}
|
||||
<Accordion.Root type="multiple" class="w-2/3 space-y-6">
|
||||
{#each archive.data as question}
|
||||
<Accordion.Item disabled={!(question.answers?.length > 0)} value={question.id}>
|
||||
<Accordion.Trigger>{question.content}?</Accordion.Trigger>
|
||||
<Accordion.Content>
|
||||
<ol class="ml-6 list-decimal [&>li]:mt-2">
|
||||
{#each question.answers as answer}
|
||||
<li>
|
||||
{answer.content}
|
||||
</li>
|
||||
{/each}
|
||||
</ol>
|
||||
</Accordion.Content>
|
||||
</Accordion.Item>
|
||||
{/each}
|
||||
</Accordion.Root>
|
||||
<Pagination.Root count={archive.meta.total} perPage={data.perPage}>
|
||||
{#snippet children({ pages, currentPage })}
|
||||
<Pagination.Content>
|
||||
<Pagination.Item>
|
||||
<Pagination.PrevButton />
|
||||
</Pagination.Item>
|
||||
{#each pages as page (page.key)}
|
||||
{#if page.type === 'ellipsis'}
|
||||
<Pagination.Item>
|
||||
<Pagination.Ellipsis />
|
||||
</Pagination.Item>
|
||||
{:else}
|
||||
<Pagination.Item isVisible={currentPage === page.value}>
|
||||
<Pagination.Link {page} isActive={currentPage === page.value}>
|
||||
{page.value}
|
||||
</Pagination.Link>
|
||||
</Pagination.Item>
|
||||
{/if}
|
||||
{/each}
|
||||
<Pagination.Item>
|
||||
<Pagination.NextButton />
|
||||
</Pagination.Item>
|
||||
</Pagination.Content>
|
||||
{/snippet}
|
||||
</Pagination.Root>
|
||||
{/await}
|
50
src/routes/vinge/rahvatarkus/answer-form.svelte
Normal file
50
src/routes/vinge/rahvatarkus/answer-form.svelte
Normal file
|
@ -0,0 +1,50 @@
|
|||
<script lang="ts">
|
||||
import { formSchema, type FormSchema } from './answer-schema';
|
||||
import type { Question } from '$lib/types';
|
||||
|
||||
import { toast } from 'svelte-sonner';
|
||||
import { zodClient } from 'sveltekit-superforms/adapters';
|
||||
import { type SuperValidated, type Infer, superForm } from 'sveltekit-superforms';
|
||||
|
||||
import * as Form from '$lib/components/ui/form/index.js';
|
||||
import { Input } from '$lib/components/ui/input/index.js';
|
||||
|
||||
let { data }: { data: { answer_form: SuperValidated<Infer<FormSchema>>; question: Question } } =
|
||||
$props();
|
||||
|
||||
const form = superForm(data.answer_form, {
|
||||
validators: zodClient(formSchema),
|
||||
onUpdated: ({ form: f }) => {
|
||||
if (f.valid) {
|
||||
toast.success(`You submitted ${JSON.stringify(f.data, null, 2)}`);
|
||||
} else {
|
||||
toast.error('Please fix the errors in the form.');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const { form: formData, enhance } = form;
|
||||
</script>
|
||||
|
||||
{#if data.question}
|
||||
<form method="POST" class="w-2/3 space-y-6" use:enhance action="?/answer">
|
||||
<Form.Field {form} name="answer">
|
||||
<Form.Control>
|
||||
{#snippet children({ props })}
|
||||
<Form.Label>{data.question.content}?</Form.Label>
|
||||
<Input {...props} bind:value={$formData.answer} />
|
||||
{/snippet}
|
||||
</Form.Control>
|
||||
<Form.FieldErrors />
|
||||
</Form.Field>
|
||||
<Form.Field {form} name="questionId">
|
||||
<Form.Control>
|
||||
{#snippet children({ props })}
|
||||
<Input type="hidden" {...props} bind:value={$formData.questionId} />
|
||||
{/snippet}
|
||||
</Form.Control>
|
||||
<Form.FieldErrors />
|
||||
</Form.Field>
|
||||
<Form.Button>Vasta</Form.Button>
|
||||
</form>
|
||||
{/if}
|
8
src/routes/vinge/rahvatarkus/answer-schema.ts
Normal file
8
src/routes/vinge/rahvatarkus/answer-schema.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
import { z } from 'zod';
|
||||
|
||||
export const formSchema = z.object({
|
||||
questionId: z.string().length(21),
|
||||
answer: z.string().min(2).max(250)
|
||||
});
|
||||
|
||||
export type FormSchema = typeof formSchema;
|
39
src/routes/vinge/rahvatarkus/question-form.svelte
Normal file
39
src/routes/vinge/rahvatarkus/question-form.svelte
Normal file
|
@ -0,0 +1,39 @@
|
|||
<script lang="ts">
|
||||
import { formSchema, type FormSchema } from './question-schema';
|
||||
|
||||
import { toast } from 'svelte-sonner';
|
||||
import { zodClient } from 'sveltekit-superforms/adapters';
|
||||
import { type SuperValidated, type Infer, superForm } from 'sveltekit-superforms';
|
||||
|
||||
import * as Form from '$lib/components/ui/form/index.js';
|
||||
import { Input } from '$lib/components/ui/input/index.js';
|
||||
|
||||
let { data }: { data: { question_form: SuperValidated<Infer<FormSchema>> } } = $props();
|
||||
|
||||
const form = superForm(data.question_form, {
|
||||
validators: zodClient(formSchema),
|
||||
onUpdated: ({ form: f }) => {
|
||||
if (f.valid) {
|
||||
toast.success(`You submitted ${JSON.stringify(f.data, null, 2)}`);
|
||||
} else {
|
||||
toast.error('Please fix the errors in the form.');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const { form: formData, enhance } = form;
|
||||
</script>
|
||||
|
||||
<form method="POST" class="w-2/3 space-y-6" use:enhance action="?/question">
|
||||
<Form.Field {form} name="question">
|
||||
<Form.Control>
|
||||
{#snippet children({ props })}
|
||||
<Form.Label>Uus küsimus</Form.Label>
|
||||
<Input {...props} bind:value={$formData.question} />
|
||||
{/snippet}
|
||||
</Form.Control>
|
||||
<Form.Description>Küsi ükskõik mida sellelt kollektiiv intelektilt.</Form.Description>
|
||||
<Form.FieldErrors />
|
||||
</Form.Field>
|
||||
<Form.Button>Küsi</Form.Button>
|
||||
</form>
|
7
src/routes/vinge/rahvatarkus/question-schema.ts
Normal file
7
src/routes/vinge/rahvatarkus/question-schema.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
import { z } from 'zod';
|
||||
|
||||
export const formSchema = z.object({
|
||||
question: z.string().min(2).max(50)
|
||||
});
|
||||
|
||||
export type FormSchema = typeof formSchema;
|
Loading…
Add table
Reference in a new issue