Adding more routes in openapi.

This commit is contained in:
Bradley Shellnut 2024-10-14 18:12:05 -07:00
parent cbcbbed912
commit 05b74e4c59
8 changed files with 288 additions and 176 deletions

View file

@ -30,7 +30,7 @@
"@playwright/test": "^1.48.0", "@playwright/test": "^1.48.0",
"@sveltejs/adapter-auto": "^3.2.5", "@sveltejs/adapter-auto": "^3.2.5",
"@sveltejs/enhanced-img": "^0.3.9", "@sveltejs/enhanced-img": "^0.3.9",
"@sveltejs/kit": "^2.7.0", "@sveltejs/kit": "^2.7.1",
"@sveltejs/vite-plugin-svelte": "4.0.0-next.7", "@sveltejs/vite-plugin-svelte": "4.0.0-next.7",
"@types/cookie": "^0.6.0", "@types/cookie": "^0.6.0",
"@types/node": "^20.16.11", "@types/node": "^20.16.11",
@ -68,7 +68,7 @@
"tslib": "^2.7.0", "tslib": "^2.7.0",
"tsx": "^4.19.1", "tsx": "^4.19.1",
"typescript": "^5.6.3", "typescript": "^5.6.3",
"vite": "^5.4.8", "vite": "^5.4.9",
"vitest": "^1.6.0", "vitest": "^1.6.0",
"zod": "^3.23.8" "zod": "^3.23.8"
}, },
@ -92,13 +92,13 @@
"@oslojs/otp": "^1.0.0", "@oslojs/otp": "^1.0.0",
"@oslojs/webauthn": "^1.0.0", "@oslojs/webauthn": "^1.0.0",
"@paralleldrive/cuid2": "^2.2.2", "@paralleldrive/cuid2": "^2.2.2",
"@scalar/hono-api-reference": "^0.5.153", "@scalar/hono-api-reference": "^0.5.154",
"@sveltejs/adapter-node": "^5.2.6", "@sveltejs/adapter-node": "^5.2.7",
"@sveltejs/adapter-vercel": "^5.4.5", "@sveltejs/adapter-vercel": "^5.4.5",
"@types/feather-icons": "^4.29.4", "@types/feather-icons": "^4.29.4",
"bits-ui": "^0.21.16", "bits-ui": "^0.21.16",
"boardgamegeekclient": "^1.9.1", "boardgamegeekclient": "^1.9.1",
"bullmq": "^5.19.1", "bullmq": "^5.20.0",
"class-variance-authority": "^0.7.0", "class-variance-authority": "^0.7.0",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"cookie": "^0.6.0", "cookie": "^0.6.0",
@ -130,10 +130,10 @@
"radix-svelte": "^0.9.0", "radix-svelte": "^0.9.0",
"rate-limit-redis": "^4.2.0", "rate-limit-redis": "^4.2.0",
"reflect-metadata": "^0.2.2", "reflect-metadata": "^0.2.2",
"stoker": "^1.0.9", "stoker": "^1.2.3",
"svelte-lazy-loader": "^1.0.0", "svelte-lazy-loader": "^1.0.0",
"svelte-sonner": "^0.3.28", "svelte-sonner": "^0.3.28",
"tailwind-merge": "^2.5.2", "tailwind-merge": "^2.5.4",
"tailwind-variants": "^0.2.1", "tailwind-variants": "^0.2.1",
"tailwindcss-animate": "^1.0.7", "tailwindcss-animate": "^1.0.7",
"tsyringe": "^4.8.0", "tsyringe": "^4.8.0",

View file

@ -63,14 +63,14 @@ importers:
specifier: ^2.2.2 specifier: ^2.2.2
version: 2.2.2 version: 2.2.2
'@scalar/hono-api-reference': '@scalar/hono-api-reference':
specifier: ^0.5.153 specifier: ^0.5.154
version: 0.5.153(hono@4.6.4) version: 0.5.154(hono@4.6.4)
'@sveltejs/adapter-node': '@sveltejs/adapter-node':
specifier: ^5.2.6 specifier: ^5.2.7
version: 5.2.6(@sveltejs/kit@2.7.0(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11))) version: 5.2.7(@sveltejs/kit@2.7.1(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))
'@sveltejs/adapter-vercel': '@sveltejs/adapter-vercel':
specifier: ^5.4.5 specifier: ^5.4.5
version: 5.4.5(@sveltejs/kit@2.7.0(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11))) version: 5.4.5(@sveltejs/kit@2.7.1(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))
'@types/feather-icons': '@types/feather-icons':
specifier: ^4.29.4 specifier: ^4.29.4
version: 4.29.4 version: 4.29.4
@ -81,8 +81,8 @@ importers:
specifier: ^1.9.1 specifier: ^1.9.1
version: 1.9.1 version: 1.9.1
bullmq: bullmq:
specifier: ^5.19.1 specifier: ^5.20.0
version: 5.19.1 version: 5.20.0
class-variance-authority: class-variance-authority:
specifier: ^0.7.0 specifier: ^0.7.0
version: 0.7.0 version: 0.7.0
@ -109,7 +109,7 @@ importers:
version: 4.29.2 version: 4.29.2
formsnap: formsnap:
specifier: ^1.0.1 specifier: ^1.0.1
version: 1.0.1(svelte@5.0.0-next.175)(sveltekit-superforms@2.19.1(@sveltejs/kit@2.7.0(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)))(@types/json-schema@7.0.15)(svelte@5.0.0-next.175)) version: 1.0.1(svelte@5.0.0-next.175)(sveltekit-superforms@2.19.1(@sveltejs/kit@2.7.1(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))(@types/json-schema@7.0.15)(svelte@5.0.0-next.175))
handlebars: handlebars:
specifier: ^4.7.8 specifier: ^4.7.8
version: 4.7.8 version: 4.7.8
@ -177,8 +177,8 @@ importers:
specifier: ^0.2.2 specifier: ^0.2.2
version: 0.2.2 version: 0.2.2
stoker: stoker:
specifier: ^1.0.9 specifier: ^1.2.3
version: 1.0.9(@asteasolutions/zod-to-openapi@7.1.2(zod@3.23.8))(@hono/zod-openapi@0.15.3(hono@4.6.4)(zod@3.23.8))(hono@4.6.4)(openapi3-ts@4.4.0) version: 1.2.3(@asteasolutions/zod-to-openapi@7.1.2(zod@3.23.8))(@hono/zod-openapi@0.15.3(hono@4.6.4)(zod@3.23.8))(hono@4.6.4)(openapi3-ts@4.4.0)
svelte-lazy-loader: svelte-lazy-loader:
specifier: ^1.0.0 specifier: ^1.0.0
version: 1.0.0 version: 1.0.0
@ -186,8 +186,8 @@ importers:
specifier: ^0.3.28 specifier: ^0.3.28
version: 0.3.28(svelte@5.0.0-next.175) version: 0.3.28(svelte@5.0.0-next.175)
tailwind-merge: tailwind-merge:
specifier: ^2.5.2 specifier: ^2.5.4
version: 2.5.3 version: 2.5.4
tailwind-variants: tailwind-variants:
specifier: ^0.2.1 specifier: ^0.2.1
version: 0.2.1(tailwindcss@3.4.13(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3))) version: 0.2.1(tailwindcss@3.4.13(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)))
@ -218,16 +218,16 @@ importers:
version: 1.48.0 version: 1.48.0
'@sveltejs/adapter-auto': '@sveltejs/adapter-auto':
specifier: ^3.2.5 specifier: ^3.2.5
version: 3.2.5(@sveltejs/kit@2.7.0(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11))) version: 3.2.5(@sveltejs/kit@2.7.1(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))
'@sveltejs/enhanced-img': '@sveltejs/enhanced-img':
specifier: ^0.3.9 specifier: ^0.3.9
version: 0.3.9(rollup@4.24.0)(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)) version: 0.3.9(rollup@4.24.0)(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11))
'@sveltejs/kit': '@sveltejs/kit':
specifier: ^2.7.0 specifier: ^2.7.1
version: 2.7.0(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)) version: 2.7.1(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11))
'@sveltejs/vite-plugin-svelte': '@sveltejs/vite-plugin-svelte':
specifier: 4.0.0-next.7 specifier: 4.0.0-next.7
version: 4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)) version: 4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11))
'@types/cookie': '@types/cookie':
specifier: ^0.6.0 specifier: ^0.6.0
version: 0.6.0 version: 0.6.0
@ -317,10 +317,10 @@ importers:
version: 2.0.2 version: 2.0.2
sveltekit-flash-message: sveltekit-flash-message:
specifier: ^2.4.4 specifier: ^2.4.4
version: 2.4.4(@sveltejs/kit@2.7.0(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)))(svelte@5.0.0-next.175) version: 2.4.4(@sveltejs/kit@2.7.1(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))(svelte@5.0.0-next.175)
sveltekit-superforms: sveltekit-superforms:
specifier: ^2.19.1 specifier: ^2.19.1
version: 2.19.1(@sveltejs/kit@2.7.0(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)))(@types/json-schema@7.0.15)(svelte@5.0.0-next.175) version: 2.19.1(@sveltejs/kit@2.7.1(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))(@types/json-schema@7.0.15)(svelte@5.0.0-next.175)
tailwindcss: tailwindcss:
specifier: ^3.4.13 specifier: ^3.4.13
version: 3.4.13(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)) version: 3.4.13(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3))
@ -337,8 +337,8 @@ importers:
specifier: ^5.6.3 specifier: ^5.6.3
version: 5.6.3 version: 5.6.3
vite: vite:
specifier: ^5.4.8 specifier: ^5.4.9
version: 5.4.8(@types/node@20.16.11) version: 5.4.9(@types/node@20.16.11)
vitest: vitest:
specifier: ^1.6.0 specifier: ^1.6.0
version: 1.6.0(@types/node@20.16.11) version: 1.6.0(@types/node@20.16.11)
@ -2143,18 +2143,18 @@ packages:
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
'@scalar/hono-api-reference@0.5.153': '@scalar/hono-api-reference@0.5.154':
resolution: {integrity: sha512-Eo4AeRanOthMI9uD/vC1GZ70ztt9aty+xoL9tUe1TUvhoTpFmGOLKzwRCFyqMSc0W16qcWXo/hkVY0BcYS+oEg==} resolution: {integrity: sha512-v5ufLt7OG27BsPqO20YtnLvIcTsRZjU5jbFbpMUguW+SFgRWh1gji2RlC4BfK5x9hrK1Ek0hz46OMYweWp4I3w==}
engines: {node: '>=18'} engines: {node: '>=18'}
peerDependencies: peerDependencies:
hono: ^4.0.0 hono: ^4.0.0
'@scalar/openapi-types@0.1.2': '@scalar/openapi-types@0.1.3':
resolution: {integrity: sha512-TxiAbs9Rw5qnMs/vvg+4Zx1Xf/5RhJXf8w6JOYSgvp4d2IKkOKc9eSOhid8ySvz7bWCjF2yWd8eHNc/BFs8cXg==} resolution: {integrity: sha512-UPUquC/ZSAdeSDbpdqMzeBVcgeytqJTj9P3QR4X9IRti5I1jXoCOUBY84CGGLXfcWquB7wfwHxn3DqQEnQmBVw==}
engines: {node: '>=18'} engines: {node: '>=18'}
'@scalar/types@0.0.14': '@scalar/types@0.0.15':
resolution: {integrity: sha512-4yzW5d9nWtRE3eVNfLnuVUScSMf325PYJ9qCJ8CpaVP7hnWrTv9xGw/2n7csEKzu3QJkdff0myibHfxXJ6ICig==} resolution: {integrity: sha512-9fSBoAuJTsmnt2FTkm/F6LRq+TIeeRI0H8wz+7J3pHfcw0YGFEZrRZOo1WZ8fpovD0fQgg+r4BPrtN8+qJ12wQ==}
engines: {node: '>=18'} engines: {node: '>=18'}
'@sideway/address@4.1.5': '@sideway/address@4.1.5':
@ -2177,8 +2177,8 @@ packages:
peerDependencies: peerDependencies:
'@sveltejs/kit': ^2.0.0 '@sveltejs/kit': ^2.0.0
'@sveltejs/adapter-node@5.2.6': '@sveltejs/adapter-node@5.2.7':
resolution: {integrity: sha512-FT9MDduZT2srUz/gDFFhQ3U2Mp9reZ3xJdJBEhr/lk+dkieSSpdgIDNNbMkm84hTaXXiC7f4cPNk8fB5nT3N2g==} resolution: {integrity: sha512-lamfhxiRIaPtuhNpJE9h8haRo/I5TzuimaiphWUGXsRCDqYWsLKtF+mo61awkBIxm+XggC4n1iaNqwf+Kt7K4Q==}
peerDependencies: peerDependencies:
'@sveltejs/kit': ^2.4.0 '@sveltejs/kit': ^2.4.0
@ -2193,8 +2193,8 @@ packages:
svelte: ^4.0.0 || ^5.0.0-next.0 svelte: ^4.0.0 || ^5.0.0-next.0
vite: '>= 5.0.0' vite: '>= 5.0.0'
'@sveltejs/kit@2.7.0': '@sveltejs/kit@2.7.1':
resolution: {integrity: sha512-4XyY1SCB/Eyz8E9G7SEBKViysYwVtDftuA7kyQ5bmuFNPWC1KZC4988rMvaJxhH2BbCTsbLPjNOZwiEGXt8/2g==} resolution: {integrity: sha512-TBVnkwgYQT3EafGQK6Eyh5FlLEBlRhCmqPTwcdOs+QdnyUc3eCAxRWtXlFxIWtmk6pqv11zdng8qTpThdTogew==}
engines: {node: '>=18.13'} engines: {node: '>=18.13'}
hasBin: true hasBin: true
peerDependencies: peerDependencies:
@ -2348,8 +2348,8 @@ packages:
'@ungap/structured-clone@1.2.0': '@ungap/structured-clone@1.2.0':
resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
'@unhead/schema@1.11.7': '@unhead/schema@1.11.9':
resolution: {integrity: sha512-j9uN7T63aUXrZ6yx2CfjVT7xZHjn0PZO7TPMaWqMFjneIH/NONKvDVCMEqDlXeqdSIERIYtk/xTHgCUMer5eyw==} resolution: {integrity: sha512-0V37bxG4sQuiLw3M5DMD+b99ndOOngecMlekQ122TDvBb24W8rWwkHhXvAu5eFg6bQXPdQF1A0U0PuRMcCj/ZA==}
'@vercel/nft@0.27.4': '@vercel/nft@0.27.4':
resolution: {integrity: sha512-Rioz3LJkEKicKCi9BSyc1RXZ5R6GmXosFMeBSThh6msWSOiArKhb7c75MiWwZEgPL7x0/l3TAfH/l0cxKNuUFA==} resolution: {integrity: sha512-Rioz3LJkEKicKCi9BSyc1RXZ5R6GmXosFMeBSThh6msWSOiArKhb7c75MiWwZEgPL7x0/l3TAfH/l0cxKNuUFA==}
@ -2554,8 +2554,8 @@ packages:
buffer@6.0.3: buffer@6.0.3:
resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==}
bullmq@5.19.1: bullmq@5.20.0:
resolution: {integrity: sha512-ziQ2C0ZS39MwerK+C1W88L4niDgrByVTogr8PeLHVEPhSHNCW39a/ROphNAdGWZ4M4hcXolloyAGgdtEz5Fw5A==} resolution: {integrity: sha512-eCJyYJqNUl9swC39x2fVm1BUv5BuO/nv2eAcAsz58znue0ZCYgSG+yWXZeauRG98Jl0UIBcPgJtbF+c9Wd+Odg==}
bytes@3.1.2: bytes@3.1.2:
resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==}
@ -4524,9 +4524,9 @@ packages:
simple-swizzle@0.2.2: simple-swizzle@0.2.2:
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
sirv@2.0.4: sirv@3.0.0:
resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==} resolution: {integrity: sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg==}
engines: {node: '>= 10'} engines: {node: '>=18'}
slash@3.0.0: slash@3.0.0:
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
@ -4567,8 +4567,8 @@ packages:
std-env@3.7.0: std-env@3.7.0:
resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==}
stoker@1.0.9: stoker@1.2.3:
resolution: {integrity: sha512-z2U3yEVKn2I0iHHQApNmppOrbfrHBEmbgcZztSFaYweOAHNxeAxEgZ2PGGAXLJHRtDgScQz5PGe9iSVgEUa/Hg==} resolution: {integrity: sha512-i1EKytlmCSHKcyO2O2x5p/z8zzUM0w7o7O2PLw8oK6RZDDu7Cy8YuPM2ERPGZ7AdXS9XpnbQq2hw5k3h3cQxrw==}
peerDependencies: peerDependencies:
'@asteasolutions/zod-to-openapi': ^7.0.0 '@asteasolutions/zod-to-openapi': ^7.0.0
'@hono/zod-openapi': ^0.16.0 '@hono/zod-openapi': ^0.16.0
@ -4786,8 +4786,8 @@ packages:
tabbable@6.2.0: tabbable@6.2.0:
resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==}
tailwind-merge@2.5.3: tailwind-merge@2.5.4:
resolution: {integrity: sha512-d9ZolCAIzom1nf/5p4LdD5zvjmgSxY0BGgdSvmXIoMYAiPdAW/dSpP7joCDYFY7r/HkEa2qmPtkgsu0xjQeQtw==} resolution: {integrity: sha512-0q8cfZHMu9nuYP/b5Shb7Y7Sh1B7Nnl5GqNr1U+n2p6+mybvRtayrQ+0042Z5byvTA8ihjlP8Odo8/VnHbZu4Q==}
tailwind-variants@0.2.1: tailwind-variants@0.2.1:
resolution: {integrity: sha512-2xmhAf4UIc3PijOUcJPA1LP4AbxhpcHuHM2C26xM0k81r0maAO6uoUSHl3APmvHZcY5cZCY/bYuJdfFa4eGoaw==} resolution: {integrity: sha512-2xmhAf4UIc3PijOUcJPA1LP4AbxhpcHuHM2C26xM0k81r0maAO6uoUSHl3APmvHZcY5cZCY/bYuJdfFa4eGoaw==}
@ -4994,8 +4994,8 @@ packages:
engines: {node: ^18.0.0 || >=20.0.0} engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true hasBin: true
vite@5.4.8: vite@5.4.9:
resolution: {integrity: sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==} resolution: {integrity: sha512-20OVpJHh0PAM0oSOELa5GaZNWeDjcAvQjGXy2Uyr+Tp+/D2/Hdz6NLgpJLsarPTA2QJ6v8mX2P1ZfbsSKvdMkg==}
engines: {node: ^18.0.0 || >=20.0.0} engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true hasBin: true
peerDependencies: peerDependencies:
@ -6507,17 +6507,17 @@ snapshots:
'@rollup/rollup-win32-x64-msvc@4.24.0': '@rollup/rollup-win32-x64-msvc@4.24.0':
optional: true optional: true
'@scalar/hono-api-reference@0.5.153(hono@4.6.4)': '@scalar/hono-api-reference@0.5.154(hono@4.6.4)':
dependencies: dependencies:
'@scalar/types': 0.0.14 '@scalar/types': 0.0.15
hono: 4.6.4 hono: 4.6.4
'@scalar/openapi-types@0.1.2': {} '@scalar/openapi-types@0.1.3': {}
'@scalar/types@0.0.14': '@scalar/types@0.0.15':
dependencies: dependencies:
'@scalar/openapi-types': 0.1.2 '@scalar/openapi-types': 0.1.3
'@unhead/schema': 1.11.7 '@unhead/schema': 1.11.9
'@sideway/address@4.1.5': '@sideway/address@4.1.5':
dependencies: dependencies:
@ -6535,41 +6535,41 @@ snapshots:
'@sinclair/typebox@0.32.35': '@sinclair/typebox@0.32.35':
optional: true optional: true
'@sveltejs/adapter-auto@3.2.5(@sveltejs/kit@2.7.0(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)))': '@sveltejs/adapter-auto@3.2.5(@sveltejs/kit@2.7.1(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))':
dependencies: dependencies:
'@sveltejs/kit': 2.7.0(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)) '@sveltejs/kit': 2.7.1(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11))
import-meta-resolve: 4.1.0 import-meta-resolve: 4.1.0
'@sveltejs/adapter-node@5.2.6(@sveltejs/kit@2.7.0(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)))': '@sveltejs/adapter-node@5.2.7(@sveltejs/kit@2.7.1(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))':
dependencies: dependencies:
'@rollup/plugin-commonjs': 28.0.0(rollup@4.24.0) '@rollup/plugin-commonjs': 28.0.0(rollup@4.24.0)
'@rollup/plugin-json': 6.1.0(rollup@4.24.0) '@rollup/plugin-json': 6.1.0(rollup@4.24.0)
'@rollup/plugin-node-resolve': 15.3.0(rollup@4.24.0) '@rollup/plugin-node-resolve': 15.3.0(rollup@4.24.0)
'@sveltejs/kit': 2.7.0(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)) '@sveltejs/kit': 2.7.1(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11))
rollup: 4.24.0 rollup: 4.24.0
'@sveltejs/adapter-vercel@5.4.5(@sveltejs/kit@2.7.0(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)))': '@sveltejs/adapter-vercel@5.4.5(@sveltejs/kit@2.7.1(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))':
dependencies: dependencies:
'@sveltejs/kit': 2.7.0(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)) '@sveltejs/kit': 2.7.1(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11))
'@vercel/nft': 0.27.4 '@vercel/nft': 0.27.4
esbuild: 0.21.5 esbuild: 0.21.5
transitivePeerDependencies: transitivePeerDependencies:
- encoding - encoding
- supports-color - supports-color
'@sveltejs/enhanced-img@0.3.9(rollup@4.24.0)(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11))': '@sveltejs/enhanced-img@0.3.9(rollup@4.24.0)(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11))':
dependencies: dependencies:
magic-string: 0.30.11 magic-string: 0.30.11
svelte: 5.0.0-next.175 svelte: 5.0.0-next.175
svelte-parse-markup: 0.1.5(svelte@5.0.0-next.175) svelte-parse-markup: 0.1.5(svelte@5.0.0-next.175)
vite: 5.4.8(@types/node@20.16.11) vite: 5.4.9(@types/node@20.16.11)
vite-imagetools: 7.0.4(rollup@4.24.0) vite-imagetools: 7.0.4(rollup@4.24.0)
transitivePeerDependencies: transitivePeerDependencies:
- rollup - rollup
'@sveltejs/kit@2.7.0(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11))': '@sveltejs/kit@2.7.1(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11))':
dependencies: dependencies:
'@sveltejs/vite-plugin-svelte': 4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)) '@sveltejs/vite-plugin-svelte': 4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11))
'@types/cookie': 0.6.0 '@types/cookie': 0.6.0
cookie: 0.6.0 cookie: 0.6.0
devalue: 5.1.1 devalue: 5.1.1
@ -6580,30 +6580,30 @@ snapshots:
mrmime: 2.0.0 mrmime: 2.0.0
sade: 1.8.1 sade: 1.8.1
set-cookie-parser: 2.7.0 set-cookie-parser: 2.7.0
sirv: 2.0.4 sirv: 3.0.0
svelte: 5.0.0-next.175 svelte: 5.0.0-next.175
tiny-glob: 0.2.9 tiny-glob: 0.2.9
vite: 5.4.8(@types/node@20.16.11) vite: 5.4.9(@types/node@20.16.11)
'@sveltejs/vite-plugin-svelte-inspector@3.0.0-next.3(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11))': '@sveltejs/vite-plugin-svelte-inspector@3.0.0-next.3(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11))':
dependencies: dependencies:
'@sveltejs/vite-plugin-svelte': 4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)) '@sveltejs/vite-plugin-svelte': 4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11))
debug: 4.3.7 debug: 4.3.7
svelte: 5.0.0-next.175 svelte: 5.0.0-next.175
vite: 5.4.8(@types/node@20.16.11) vite: 5.4.9(@types/node@20.16.11)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11))': '@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11))':
dependencies: dependencies:
'@sveltejs/vite-plugin-svelte-inspector': 3.0.0-next.3(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)) '@sveltejs/vite-plugin-svelte-inspector': 3.0.0-next.3(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11))
debug: 4.3.7 debug: 4.3.7
deepmerge: 4.3.1 deepmerge: 4.3.1
kleur: 4.1.5 kleur: 4.1.5
magic-string: 0.30.11 magic-string: 0.30.11
svelte: 5.0.0-next.175 svelte: 5.0.0-next.175
vite: 5.4.8(@types/node@20.16.11) vite: 5.4.9(@types/node@20.16.11)
vitefu: 1.0.2(vite@5.4.8(@types/node@20.16.11)) vitefu: 1.0.2(vite@5.4.9(@types/node@20.16.11))
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -6762,7 +6762,7 @@ snapshots:
'@ungap/structured-clone@1.2.0': {} '@ungap/structured-clone@1.2.0': {}
'@unhead/schema@1.11.7': '@unhead/schema@1.11.9':
dependencies: dependencies:
hookable: 5.5.3 hookable: 5.5.3
zhead: 2.2.4 zhead: 2.2.4
@ -7008,7 +7008,7 @@ snapshots:
base64-js: 1.5.1 base64-js: 1.5.1
ieee754: 1.2.1 ieee754: 1.2.1
bullmq@5.19.1: bullmq@5.20.0:
dependencies: dependencies:
cron-parser: 4.9.0 cron-parser: 4.9.0
ioredis: 5.4.1 ioredis: 5.4.1
@ -7713,11 +7713,11 @@ snapshots:
cross-spawn: 7.0.3 cross-spawn: 7.0.3
signal-exit: 4.1.0 signal-exit: 4.1.0
formsnap@1.0.1(svelte@5.0.0-next.175)(sveltekit-superforms@2.19.1(@sveltejs/kit@2.7.0(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)))(@types/json-schema@7.0.15)(svelte@5.0.0-next.175)): formsnap@1.0.1(svelte@5.0.0-next.175)(sveltekit-superforms@2.19.1(@sveltejs/kit@2.7.1(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))(@types/json-schema@7.0.15)(svelte@5.0.0-next.175)):
dependencies: dependencies:
nanoid: 5.0.7 nanoid: 5.0.7
svelte: 5.0.0-next.175 svelte: 5.0.0-next.175
sveltekit-superforms: 2.19.1(@sveltejs/kit@2.7.0(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)))(@types/json-schema@7.0.15)(svelte@5.0.0-next.175) sveltekit-superforms: 2.19.1(@sveltejs/kit@2.7.1(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))(@types/json-schema@7.0.15)(svelte@5.0.0-next.175)
forwarded@0.2.0: {} forwarded@0.2.0: {}
@ -9063,7 +9063,7 @@ snapshots:
dependencies: dependencies:
is-arrayish: 0.3.2 is-arrayish: 0.3.2
sirv@2.0.4: sirv@3.0.0:
dependencies: dependencies:
'@polka/url': 1.0.0-next.28 '@polka/url': 1.0.0-next.28
mrmime: 2.0.0 mrmime: 2.0.0
@ -9101,7 +9101,7 @@ snapshots:
std-env@3.7.0: {} std-env@3.7.0: {}
stoker@1.0.9(@asteasolutions/zod-to-openapi@7.1.2(zod@3.23.8))(@hono/zod-openapi@0.15.3(hono@4.6.4)(zod@3.23.8))(hono@4.6.4)(openapi3-ts@4.4.0): stoker@1.2.3(@asteasolutions/zod-to-openapi@7.1.2(zod@3.23.8))(@hono/zod-openapi@0.15.3(hono@4.6.4)(zod@3.23.8))(hono@4.6.4)(openapi3-ts@4.4.0):
dependencies: dependencies:
'@asteasolutions/zod-to-openapi': 7.1.2(zod@3.23.8) '@asteasolutions/zod-to-openapi': 7.1.2(zod@3.23.8)
hono: 4.6.4 hono: 4.6.4
@ -9292,14 +9292,14 @@ snapshots:
magic-string: 0.30.11 magic-string: 0.30.11
zimmerframe: 1.1.2 zimmerframe: 1.1.2
sveltekit-flash-message@2.4.4(@sveltejs/kit@2.7.0(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)))(svelte@5.0.0-next.175): sveltekit-flash-message@2.4.4(@sveltejs/kit@2.7.1(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))(svelte@5.0.0-next.175):
dependencies: dependencies:
'@sveltejs/kit': 2.7.0(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)) '@sveltejs/kit': 2.7.1(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11))
svelte: 5.0.0-next.175 svelte: 5.0.0-next.175
sveltekit-superforms@2.19.1(@sveltejs/kit@2.7.0(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)))(@types/json-schema@7.0.15)(svelte@5.0.0-next.175): sveltekit-superforms@2.19.1(@sveltejs/kit@2.7.1(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))(@types/json-schema@7.0.15)(svelte@5.0.0-next.175):
dependencies: dependencies:
'@sveltejs/kit': 2.7.0(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.8(@types/node@20.16.11)) '@sveltejs/kit': 2.7.1(@sveltejs/vite-plugin-svelte@4.0.0-next.7(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11)))(svelte@5.0.0-next.175)(vite@5.4.9(@types/node@20.16.11))
devalue: 5.1.1 devalue: 5.1.1
just-clone: 6.2.0 just-clone: 6.2.0
memoize-weak: 1.0.2 memoize-weak: 1.0.2
@ -9325,11 +9325,11 @@ snapshots:
tabbable@6.2.0: {} tabbable@6.2.0: {}
tailwind-merge@2.5.3: {} tailwind-merge@2.5.4: {}
tailwind-variants@0.2.1(tailwindcss@3.4.13(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3))): tailwind-variants@0.2.1(tailwindcss@3.4.13(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3))):
dependencies: dependencies:
tailwind-merge: 2.5.3 tailwind-merge: 2.5.4
tailwindcss: 3.4.13(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3)) tailwindcss: 3.4.13(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3))
tailwindcss-animate@1.0.7(tailwindcss@3.4.13(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3))): tailwindcss-animate@1.0.7(tailwindcss@3.4.13(ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3))):
@ -9532,7 +9532,7 @@ snapshots:
debug: 4.3.7 debug: 4.3.7
pathe: 1.1.2 pathe: 1.1.2
picocolors: 1.1.0 picocolors: 1.1.0
vite: 5.4.8(@types/node@20.16.11) vite: 5.4.9(@types/node@20.16.11)
transitivePeerDependencies: transitivePeerDependencies:
- '@types/node' - '@types/node'
- less - less
@ -9544,7 +9544,7 @@ snapshots:
- supports-color - supports-color
- terser - terser
vite@5.4.8(@types/node@20.16.11): vite@5.4.9(@types/node@20.16.11):
dependencies: dependencies:
esbuild: 0.21.5 esbuild: 0.21.5
postcss: 8.4.47 postcss: 8.4.47
@ -9553,9 +9553,9 @@ snapshots:
'@types/node': 20.16.11 '@types/node': 20.16.11
fsevents: 2.3.3 fsevents: 2.3.3
vitefu@1.0.2(vite@5.4.8(@types/node@20.16.11)): vitefu@1.0.2(vite@5.4.9(@types/node@20.16.11)):
optionalDependencies: optionalDependencies:
vite: 5.4.8(@types/node@20.16.11) vite: 5.4.9(@types/node@20.16.11)
vitest@1.6.0(@types/node@20.16.11): vitest@1.6.0(@types/node@20.16.11):
dependencies: dependencies:
@ -9576,7 +9576,7 @@ snapshots:
strip-literal: 2.1.0 strip-literal: 2.1.0
tinybench: 2.9.0 tinybench: 2.9.0
tinypool: 0.8.4 tinypool: 0.8.4
vite: 5.4.8(@types/node@20.16.11) vite: 5.4.9(@types/node@20.16.11)
vite-node: 1.6.0(@types/node@20.16.11) vite-node: 1.6.0(@types/node@20.16.11)
why-is-node-running: 2.3.0 why-is-node-running: 2.3.0
optionalDependencies: optionalDependencies:

View file

@ -0,0 +1,7 @@
import { z } from '@hono/zod-openapi';
const cuidParamsSchema = z.object({
cuid: z.string().cuid2(),
});
export default cuidParamsSchema;

View file

@ -1,32 +1,40 @@
import 'reflect-metadata' import 'reflect-metadata';
import { Controller } from '$lib/server/api/common/types/controller' import { StatusCodes } from '$lib/constants/status-codes';
import { CollectionsService } from '$lib/server/api/services/collections.service' import { Controller } from '$lib/server/api/common/types/controller';
import { inject, injectable } from 'tsyringe' import { allCollections, getCollectionByCUID, numberOfCollections } from '$lib/server/api/controllers/collection.routes';
import { requireAuth } from '../middleware/require-auth.middleware' import { CollectionsService } from '$lib/server/api/services/collections.service';
import { openApi } from 'hono-zod-openapi';
import { inject, injectable } from 'tsyringe';
import { requireAuth } from '../middleware/require-auth.middleware';
@injectable() @injectable()
export class CollectionController extends Controller { export class CollectionController extends Controller {
constructor(@inject(CollectionsService) private readonly collectionsService: CollectionsService) { constructor(@inject(CollectionsService) private readonly collectionsService: CollectionsService) {
super() super();
} }
routes() { routes() {
return this.controller return this.controller
.get('/', requireAuth, async (c) => { .get('/', requireAuth, openApi(allCollections), async (c) => {
const user = c.var.user const user = c.var.user;
const collections = await this.collectionsService.findAllByUserId(user.id) const collections = await this.collectionsService.findAllByUserId(user.id);
console.log('collections service', collections) console.log('collections service', collections);
return c.json({ collections }) return c.json({ collections }, StatusCodes.OK);
}) })
.get('/count', requireAuth, async (c) => { .get('/count', requireAuth, openApi(numberOfCollections), async (c) => {
const user = c.var.user const user = c.var.user;
const collections = await this.collectionsService.findAllByUserIdWithDetails(user.id) const collections = await this.collectionsService.findAllByUserIdWithDetails(user.id);
return c.json({ collections }) return c.json({ count: collections?.length || 0 }, StatusCodes.OK);
})
.get('/:cuid', requireAuth, async (c) => {
const cuid = c.req.param('cuid')
const collection = await this.collectionsService.findOneByCuid(cuid)
return c.json({ collection })
}) })
.get('/:cuid', requireAuth, openApi(getCollectionByCUID), async (c) => {
const cuid = c.req.param('cuid');
const collection = await this.collectionsService.findOneByCuid(cuid);
if (!collection) {
return c.json('Collection not found', StatusCodes.NOT_FOUND);
}
return c.json({ collection }, StatusCodes.OK);
});
} }
} }

View file

@ -0,0 +1,69 @@
import { StatusCodes } from '$lib/constants/status-codes';
import { unauthorizedSchema } from '$lib/server/api/common/exceptions';
import cuidParamsSchema from '$lib/server/api/common/openapi/cuidParamsSchema';
import { selectCollectionSchema } from '$lib/server/api/databases/tables';
import { z } from '@hono/zod-openapi';
import { IdParamsSchema } from 'stoker/openapi/schemas';
import { createErrorSchema } from 'stoker/openapi/schemas';
import { taggedAuthRoute } from '../common/openapi/create-auth-route';
const tag = 'Collection';
export const allCollections = taggedAuthRoute(tag, {
responses: {
[StatusCodes.OK]: {
description: 'User profile',
schema: selectCollectionSchema,
mediaType: 'application/json',
},
[StatusCodes.UNAUTHORIZED]: {
description: 'Unauthorized',
schema: createErrorSchema(unauthorizedSchema),
mediaType: 'application/json',
},
},
});
export const numberOfCollections = taggedAuthRoute(tag, {
responses: {
[StatusCodes.OK]: {
description: 'User profile',
mediaType: 'application/json',
},
[StatusCodes.UNAUTHORIZED]: {
description: 'Unauthorized',
schema: createErrorSchema(unauthorizedSchema),
mediaType: 'application/json',
},
},
});
export const getCollectionByCUID = taggedAuthRoute(tag, {
request: {
param: {
schema: cuidParamsSchema,
example: { cuid: 'z6uiuc9qz82xjf5dexc5kr2d' },
},
},
responses: {
[StatusCodes.OK]: {
description: 'User profile',
schema: selectCollectionSchema,
mediaType: 'application/json',
},
[StatusCodes.NOT_FOUND]: {
description: 'The collection does not exist',
schema: z.object({ message: z.string() }).openapi({
example: {
message: 'The collection does not exist',
},
}),
mediaType: 'application/json',
},
[StatusCodes.UNAUTHORIZED]: {
description: 'Unauthorized',
schema: createErrorSchema(unauthorizedSchema),
mediaType: 'application/json',
},
},
});

View file

@ -47,51 +47,72 @@ export class IamController extends Controller {
return c.json({ user: updatedUser }, StatusCodes.OK); return c.json({ user: updatedUser }, StatusCodes.OK);
}, },
) )
.post('/verify/password', requireAuth, zValidator('json', verifyPasswordDto), openApi(verifyPassword), limiter({ limit: 10, minutes: 60 }), async (c) => { .post(
const user = c.var.user; '/verify/password',
const { password } = c.req.valid('json'); requireAuth,
const passwordVerified = await this.iamService.verifyPassword(user.id, { password }); zValidator('json', verifyPasswordDto),
if (!passwordVerified) { openApi(verifyPassword),
console.log('Incorrect password'); limiter({ limit: 10, minutes: 60 }),
return c.json('Incorrect password', StatusCodes.BAD_GATEWAY); async (c) => {
} const user = c.var.user;
return c.json({}, StatusCodes.OK); const { password } = c.req.valid('json');
}) const passwordVerified = await this.iamService.verifyPassword(user.id, { password });
.put('/update/password', requireAuth, openApi(updatePassword), zValidator('json', changePasswordDto), limiter({ limit: 10, minutes: 60 }), async (c) => { if (!passwordVerified) {
const user = c.var.user; console.log('Incorrect password');
const { password, confirm_password } = c.req.valid('json'); return c.json('Incorrect password', StatusCodes.FORBIDDEN);
if (password !== confirm_password) { }
return c.json('Passwords do not match', StatusCodes.UNPROCESSABLE_ENTITY); return c.json({}, StatusCodes.OK);
} },
try { )
await this.iamService.updatePassword(user.id, { password, confirm_password }); .put(
await this.luciaService.lucia.invalidateUserSessions(user.id); '/update/password',
await this.loginRequestService.createUserSession(user.id, c.req, undefined); requireAuth,
const sessionCookie = this.luciaService.lucia.createBlankSessionCookie(); openApi(updatePassword),
setCookie(c, sessionCookie.name, sessionCookie.value, { zValidator('json', changePasswordDto),
path: sessionCookie.attributes.path, limiter({ limit: 10, minutes: 60 }),
maxAge: sessionCookie.attributes.maxAge, async (c) => {
domain: sessionCookie.attributes.domain, const user = c.var.user;
sameSite: sessionCookie.attributes.sameSite as any, const { password, confirm_password } = c.req.valid('json');
secure: sessionCookie.attributes.secure, if (password !== confirm_password) {
httpOnly: sessionCookie.attributes.httpOnly, return c.json('Passwords do not match', StatusCodes.UNPROCESSABLE_ENTITY);
expires: sessionCookie.attributes.expires, }
}); try {
return c.json({ status: 'success' }); await this.iamService.updatePassword(user.id, { password, confirm_password });
} catch (error) { await this.luciaService.lucia.invalidateUserSessions(user.id);
console.error('Error updating password', error); await this.loginRequestService.createUserSession(user.id, c.req, undefined);
return c.json('Error updating password', StatusCodes.UNPROCESSABLE_ENTITY); const sessionCookie = this.luciaService.lucia.createBlankSessionCookie();
} setCookie(c, sessionCookie.name, sessionCookie.value, {
}) path: sessionCookie.attributes.path,
.post('/update/email', requireAuth, openApi(updateEmail), zValidator('json', updateEmailDto), limiter({ limit: 10, minutes: 60 }), async (c) => { maxAge: sessionCookie.attributes.maxAge,
const user = c.var.user; domain: sessionCookie.attributes.domain,
const { email } = c.req.valid('json'); sameSite: sessionCookie.attributes.sameSite as any,
const updatedUser = await this.iamService.updateEmail(user.id, { email }); secure: sessionCookie.attributes.secure,
if (!updatedUser) { httpOnly: sessionCookie.attributes.httpOnly,
return c.json('Cannot change email address', StatusCodes.BAD_REQUEST); expires: sessionCookie.attributes.expires,
} });
return c.json({ user: updatedUser }, StatusCodes.OK); return c.json({ status: 'success' });
}) } catch (error) {
console.error('Error updating password', error);
return c.json('Error updating password', StatusCodes.INTERNAL_SERVER_ERROR);
}
},
)
.post(
'/update/email',
requireAuth,
openApi(updateEmail),
zValidator('json', updateEmailDto),
limiter({ limit: 10, minutes: 60 }),
async (c) => {
const user = c.var.user;
const { email } = c.req.valid('json');
const updatedUser = await this.iamService.updateEmail(user.id, { email });
if (!updatedUser) {
return c.json('Cannot change email address', StatusCodes.FORBIDDEN);
}
return c.json({ user: updatedUser }, StatusCodes.OK);
},
)
.post('/logout', requireAuth, openApi(logout), async (c) => { .post('/logout', requireAuth, openApi(logout), async (c) => {
const sessionId = c.var.session.id; const sessionId = c.var.session.id;
await this.iamService.logout(sessionId); await this.iamService.logout(sessionId);

View file

@ -65,7 +65,7 @@ export const verifyPassword = taggedAuthRoute(tag, {
schema: createErrorSchema(verifyPasswordDto), schema: createErrorSchema(verifyPasswordDto),
mediaType: 'application/json', mediaType: 'application/json',
}, },
[StatusCodes.BAD_REQUEST]: { [StatusCodes.UNPROCESSABLE_ENTITY]: {
description: 'Incorrect password', description: 'Incorrect password',
mediaType: 'application/json', mediaType: 'application/json',
}, },
@ -91,15 +91,19 @@ export const updatePassword = taggedAuthRoute(tag, {
schema: createErrorSchema(changePasswordDto), schema: createErrorSchema(changePasswordDto),
mediaType: 'application/json', mediaType: 'application/json',
}, },
[StatusCodes.BAD_REQUEST]: {
description: 'Incorrect password',
mediaType: 'application/json',
},
[StatusCodes.UNAUTHORIZED]: { [StatusCodes.UNAUTHORIZED]: {
description: 'Unauthorized', description: 'Unauthorized',
schema: createErrorSchema(unauthorizedSchema), schema: createErrorSchema(unauthorizedSchema),
mediaType: 'application/json', mediaType: 'application/json',
}, },
[StatusCodes.FORBIDDEN]: {
description: 'Incorrect password',
mediaType: 'application/json',
},
[StatusCodes.INTERNAL_SERVER_ERROR]: {
description: 'Error updating password',
mediaType: 'application/json',
},
}, },
}); });
@ -114,15 +118,15 @@ export const updateEmail = taggedAuthRoute(tag, {
schema: createErrorSchema(changePasswordDto), schema: createErrorSchema(changePasswordDto),
mediaType: 'application/json', mediaType: 'application/json',
}, },
[StatusCodes.BAD_REQUEST]: {
description: "Cannot change email address",
mediaType: 'application/json',
},
[StatusCodes.UNAUTHORIZED]: { [StatusCodes.UNAUTHORIZED]: {
description: 'Unauthorized', description: 'Unauthorized',
schema: createErrorSchema(unauthorizedSchema), schema: createErrorSchema(unauthorizedSchema),
mediaType: 'application/json', mediaType: 'application/json',
}, },
[StatusCodes.FORBIDDEN]: {
description: 'Cannot change email address',
mediaType: 'application/json',
},
}, },
}); });

View file

@ -1,9 +1,10 @@
import { createId as cuid2 } from '@paralleldrive/cuid2' import { createId as cuid2 } from '@paralleldrive/cuid2';
import { type InferSelectModel, relations } from 'drizzle-orm' import { type InferSelectModel, relations } from 'drizzle-orm';
import { pgTable, text, uuid } from 'drizzle-orm/pg-core' import { pgTable, text, uuid } from 'drizzle-orm/pg-core';
import { timestamps } from '../../common/utils/table' import { createSelectSchema } from 'drizzle-zod';
import { usersTable } from './users.table' import { timestamps } from '../../common/utils/table';
import { collection_items } from './collectionItems.table' import { collection_items } from './collectionItems.table';
import { usersTable } from './users.table';
export const collections = pgTable('collections', { export const collections = pgTable('collections', {
id: uuid('id').primaryKey().defaultRandom(), id: uuid('id').primaryKey().defaultRandom(),
@ -15,7 +16,7 @@ export const collections = pgTable('collections', {
.references(() => usersTable.id, { onDelete: 'cascade' }), .references(() => usersTable.id, { onDelete: 'cascade' }),
name: text('name').notNull().default('My Collection'), name: text('name').notNull().default('My Collection'),
...timestamps, ...timestamps,
}) });
export const collection_relations = relations(collections, ({ one, many }) => ({ export const collection_relations = relations(collections, ({ one, many }) => ({
user: one(usersTable, { user: one(usersTable, {
@ -23,6 +24,8 @@ export const collection_relations = relations(collections, ({ one, many }) => ({
references: [usersTable.id], references: [usersTable.id],
}), }),
collection_items: many(collection_items), collection_items: many(collection_items),
})) }));
export type Collections = InferSelectModel<typeof collections> export const selectCollectionSchema = createSelectSchema(collections);
export type Collections = InferSelectModel<typeof collections>;