├── .gitignore ├── README.md ├── next-env.d.ts ├── next.config.ts ├── package.json ├── pnpm-lock.yaml ├── src ├── pages │ ├── _app.tsx │ ├── api │ │ └── trpc │ │ │ └── [trpc].ts │ ├── index.tsx │ ├── react-hook-form.tsx │ └── vanilla.tsx ├── server │ ├── routers │ │ ├── room.ts │ │ └── viewer.ts │ └── trpc.ts └── utils │ ├── schemas.ts │ ├── trpc.ts │ └── writeFileToDisk.ts └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | public/uploads -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Next.js + tRPC + `FormData` 2 | 3 | This example showcases how to use tRPC with `FormData`. 4 | 5 | ## Setup 6 | 7 | ```bash 8 | npx create-next-app --example https://github.com/trpc/trpc --example-path examples/next-formdata trpc-formdata 9 | cd trpc-formdata 10 | npm i 11 | npm run dev 12 | ``` 13 | -------------------------------------------------------------------------------- /next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /next.config.ts: -------------------------------------------------------------------------------- 1 | import { NextConfig } from 'next'; 2 | 3 | export default { 4 | /** We run eslint as a separate task in CI */ 5 | eslint: { ignoreDuringBuilds: !!process.env.CI }, 6 | } satisfies NextConfig; 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "examples-next-formdata", 3 | "private": true, 4 | "scripts": { 5 | "dev": "next dev", 6 | "build": "next build", 7 | "lint": "eslint src", 8 | "start": "next start" 9 | }, 10 | "dependencies": { 11 | "@hookform/error-message": "^2.0.1", 12 | "@hookform/resolvers": "^3.9.1", 13 | "@tanstack/react-query": "^5.80.3", 14 | "@trpc/client": "next", 15 | "@trpc/next": "next", 16 | "@trpc/react-query": "next", 17 | "@trpc/server": "next", 18 | "next": "^15.3.1", 19 | "react": "^19.1.0", 20 | "react-dom": "^19.1.0", 21 | "react-hook-form": "^7.53.2", 22 | "zod": "^3.25.51", 23 | "zod-form-data": "^2.0.1" 24 | }, 25 | "devDependencies": { 26 | "@types/node": "^22.13.5", 27 | "@types/react": "^19.1.0", 28 | "@types/react-dom": "^19.1.1", 29 | "eslint": "^9.26.0", 30 | "typescript": "^5.8.2" 31 | }, 32 | "version": "11.3.1" 33 | } 34 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '9.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | importers: 8 | 9 | .: 10 | dependencies: 11 | '@hookform/error-message': 12 | specifier: ^2.0.1 13 | version: 2.0.1(react-dom@19.1.0(react@19.1.0))(react-hook-form@7.57.0(react@19.1.0))(react@19.1.0) 14 | '@hookform/resolvers': 15 | specifier: ^3.9.1 16 | version: 3.10.0(react-hook-form@7.57.0(react@19.1.0)) 17 | '@tanstack/react-query': 18 | specifier: ^5.80.3 19 | version: 5.80.6(react@19.1.0) 20 | '@trpc/client': 21 | specifier: next 22 | version: 11.0.0(@trpc/server@11.0.0(typescript@5.8.3))(typescript@5.8.3) 23 | '@trpc/next': 24 | specifier: next 25 | version: 11.0.0(@tanstack/react-query@5.80.6(react@19.1.0))(@trpc/client@11.0.0(@trpc/server@11.0.0(typescript@5.8.3))(typescript@5.8.3))(@trpc/react-query@11.0.0(@tanstack/react-query@5.80.6(react@19.1.0))(@trpc/client@11.0.0(@trpc/server@11.0.0(typescript@5.8.3))(typescript@5.8.3))(@trpc/server@11.0.0(typescript@5.8.3))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.8.3))(@trpc/server@11.0.0(typescript@5.8.3))(next@15.3.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.8.3) 26 | '@trpc/react-query': 27 | specifier: next 28 | version: 11.0.0(@tanstack/react-query@5.80.6(react@19.1.0))(@trpc/client@11.0.0(@trpc/server@11.0.0(typescript@5.8.3))(typescript@5.8.3))(@trpc/server@11.0.0(typescript@5.8.3))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.8.3) 29 | '@trpc/server': 30 | specifier: next 31 | version: 11.0.0(typescript@5.8.3) 32 | next: 33 | specifier: ^15.3.1 34 | version: 15.3.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0) 35 | react: 36 | specifier: ^19.1.0 37 | version: 19.1.0 38 | react-dom: 39 | specifier: ^19.1.0 40 | version: 19.1.0(react@19.1.0) 41 | react-hook-form: 42 | specifier: ^7.53.2 43 | version: 7.57.0(react@19.1.0) 44 | zod: 45 | specifier: ^3.25.51 46 | version: 3.25.51 47 | zod-form-data: 48 | specifier: ^2.0.1 49 | version: 2.0.7(zod@3.25.51) 50 | devDependencies: 51 | '@types/node': 52 | specifier: ^22.13.5 53 | version: 22.15.30 54 | '@types/react': 55 | specifier: ^19.1.0 56 | version: 19.1.6 57 | '@types/react-dom': 58 | specifier: ^19.1.1 59 | version: 19.1.6(@types/react@19.1.6) 60 | eslint: 61 | specifier: ^9.26.0 62 | version: 9.28.0 63 | typescript: 64 | specifier: ^5.8.2 65 | version: 5.8.3 66 | 67 | packages: 68 | 69 | '@emnapi/runtime@1.4.3': 70 | resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==} 71 | 72 | '@eslint-community/eslint-utils@4.7.0': 73 | resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} 74 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 75 | peerDependencies: 76 | eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 77 | 78 | '@eslint-community/regexpp@4.12.1': 79 | resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} 80 | engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} 81 | 82 | '@eslint/config-array@0.20.0': 83 | resolution: {integrity: sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==} 84 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 85 | 86 | '@eslint/config-helpers@0.2.2': 87 | resolution: {integrity: sha512-+GPzk8PlG0sPpzdU5ZvIRMPidzAnZDl/s9L+y13iodqvb8leL53bTannOrQ/Im7UkpsmFU5Ily5U60LWixnmLg==} 88 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 89 | 90 | '@eslint/core@0.14.0': 91 | resolution: {integrity: sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==} 92 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 93 | 94 | '@eslint/eslintrc@3.3.1': 95 | resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} 96 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 97 | 98 | '@eslint/js@9.28.0': 99 | resolution: {integrity: sha512-fnqSjGWd/CoIp4EXIxWVK/sHA6DOHN4+8Ix2cX5ycOY7LG0UY8nHCU5pIp2eaE1Mc7Qd8kHspYNzYXT2ojPLzg==} 100 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 101 | 102 | '@eslint/object-schema@2.1.6': 103 | resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} 104 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 105 | 106 | '@eslint/plugin-kit@0.3.1': 107 | resolution: {integrity: sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w==} 108 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 109 | 110 | '@hookform/error-message@2.0.1': 111 | resolution: {integrity: sha512-U410sAr92xgxT1idlu9WWOVjndxLdgPUHEB8Schr27C9eh7/xUnITWpCMF93s+lGiG++D4JnbSnrb5A21AdSNg==} 112 | peerDependencies: 113 | react: '>=16.8.0' 114 | react-dom: '>=16.8.0' 115 | react-hook-form: ^7.0.0 116 | 117 | '@hookform/resolvers@3.10.0': 118 | resolution: {integrity: sha512-79Dv+3mDF7i+2ajj7SkypSKHhl1cbln1OGavqrsF7p6mbUv11xpqpacPsGDCTRvCSjEEIez2ef1NveSVL3b0Ag==} 119 | peerDependencies: 120 | react-hook-form: ^7.0.0 121 | 122 | '@humanfs/core@0.19.1': 123 | resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} 124 | engines: {node: '>=18.18.0'} 125 | 126 | '@humanfs/node@0.16.6': 127 | resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} 128 | engines: {node: '>=18.18.0'} 129 | 130 | '@humanwhocodes/module-importer@1.0.1': 131 | resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} 132 | engines: {node: '>=12.22'} 133 | 134 | '@humanwhocodes/retry@0.3.1': 135 | resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} 136 | engines: {node: '>=18.18'} 137 | 138 | '@humanwhocodes/retry@0.4.3': 139 | resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} 140 | engines: {node: '>=18.18'} 141 | 142 | '@img/sharp-darwin-arm64@0.34.2': 143 | resolution: {integrity: sha512-OfXHZPppddivUJnqyKoi5YVeHRkkNE2zUFT2gbpKxp/JZCFYEYubnMg+gOp6lWfasPrTS+KPosKqdI+ELYVDtg==} 144 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 145 | cpu: [arm64] 146 | os: [darwin] 147 | 148 | '@img/sharp-darwin-x64@0.34.2': 149 | resolution: {integrity: sha512-dYvWqmjU9VxqXmjEtjmvHnGqF8GrVjM2Epj9rJ6BUIXvk8slvNDJbhGFvIoXzkDhrJC2jUxNLz/GUjjvSzfw+g==} 150 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 151 | cpu: [x64] 152 | os: [darwin] 153 | 154 | '@img/sharp-libvips-darwin-arm64@1.1.0': 155 | resolution: {integrity: sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==} 156 | cpu: [arm64] 157 | os: [darwin] 158 | 159 | '@img/sharp-libvips-darwin-x64@1.1.0': 160 | resolution: {integrity: sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==} 161 | cpu: [x64] 162 | os: [darwin] 163 | 164 | '@img/sharp-libvips-linux-arm64@1.1.0': 165 | resolution: {integrity: sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==} 166 | cpu: [arm64] 167 | os: [linux] 168 | 169 | '@img/sharp-libvips-linux-arm@1.1.0': 170 | resolution: {integrity: sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==} 171 | cpu: [arm] 172 | os: [linux] 173 | 174 | '@img/sharp-libvips-linux-ppc64@1.1.0': 175 | resolution: {integrity: sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==} 176 | cpu: [ppc64] 177 | os: [linux] 178 | 179 | '@img/sharp-libvips-linux-s390x@1.1.0': 180 | resolution: {integrity: sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==} 181 | cpu: [s390x] 182 | os: [linux] 183 | 184 | '@img/sharp-libvips-linux-x64@1.1.0': 185 | resolution: {integrity: sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==} 186 | cpu: [x64] 187 | os: [linux] 188 | 189 | '@img/sharp-libvips-linuxmusl-arm64@1.1.0': 190 | resolution: {integrity: sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==} 191 | cpu: [arm64] 192 | os: [linux] 193 | 194 | '@img/sharp-libvips-linuxmusl-x64@1.1.0': 195 | resolution: {integrity: sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==} 196 | cpu: [x64] 197 | os: [linux] 198 | 199 | '@img/sharp-linux-arm64@0.34.2': 200 | resolution: {integrity: sha512-D8n8wgWmPDakc83LORcfJepdOSN6MvWNzzz2ux0MnIbOqdieRZwVYY32zxVx+IFUT8er5KPcyU3XXsn+GzG/0Q==} 201 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 202 | cpu: [arm64] 203 | os: [linux] 204 | 205 | '@img/sharp-linux-arm@0.34.2': 206 | resolution: {integrity: sha512-0DZzkvuEOqQUP9mo2kjjKNok5AmnOr1jB2XYjkaoNRwpAYMDzRmAqUIa1nRi58S2WswqSfPOWLNOr0FDT3H5RQ==} 207 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 208 | cpu: [arm] 209 | os: [linux] 210 | 211 | '@img/sharp-linux-s390x@0.34.2': 212 | resolution: {integrity: sha512-EGZ1xwhBI7dNISwxjChqBGELCWMGDvmxZXKjQRuqMrakhO8QoMgqCrdjnAqJq/CScxfRn+Bb7suXBElKQpPDiw==} 213 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 214 | cpu: [s390x] 215 | os: [linux] 216 | 217 | '@img/sharp-linux-x64@0.34.2': 218 | resolution: {integrity: sha512-sD7J+h5nFLMMmOXYH4DD9UtSNBD05tWSSdWAcEyzqW8Cn5UxXvsHAxmxSesYUsTOBmUnjtxghKDl15EvfqLFbQ==} 219 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 220 | cpu: [x64] 221 | os: [linux] 222 | 223 | '@img/sharp-linuxmusl-arm64@0.34.2': 224 | resolution: {integrity: sha512-NEE2vQ6wcxYav1/A22OOxoSOGiKnNmDzCYFOZ949xFmrWZOVII1Bp3NqVVpvj+3UeHMFyN5eP/V5hzViQ5CZNA==} 225 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 226 | cpu: [arm64] 227 | os: [linux] 228 | 229 | '@img/sharp-linuxmusl-x64@0.34.2': 230 | resolution: {integrity: sha512-DOYMrDm5E6/8bm/yQLCWyuDJwUnlevR8xtF8bs+gjZ7cyUNYXiSf/E8Kp0Ss5xasIaXSHzb888V1BE4i1hFhAA==} 231 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 232 | cpu: [x64] 233 | os: [linux] 234 | 235 | '@img/sharp-wasm32@0.34.2': 236 | resolution: {integrity: sha512-/VI4mdlJ9zkaq53MbIG6rZY+QRN3MLbR6usYlgITEzi4Rpx5S6LFKsycOQjkOGmqTNmkIdLjEvooFKwww6OpdQ==} 237 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 238 | cpu: [wasm32] 239 | 240 | '@img/sharp-win32-arm64@0.34.2': 241 | resolution: {integrity: sha512-cfP/r9FdS63VA5k0xiqaNaEoGxBg9k7uE+RQGzuK9fHt7jib4zAVVseR9LsE4gJcNWgT6APKMNnCcnyOtmSEUQ==} 242 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 243 | cpu: [arm64] 244 | os: [win32] 245 | 246 | '@img/sharp-win32-ia32@0.34.2': 247 | resolution: {integrity: sha512-QLjGGvAbj0X/FXl8n1WbtQ6iVBpWU7JO94u/P2M4a8CFYsvQi4GW2mRy/JqkRx0qpBzaOdKJKw8uc930EX2AHw==} 248 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 249 | cpu: [ia32] 250 | os: [win32] 251 | 252 | '@img/sharp-win32-x64@0.34.2': 253 | resolution: {integrity: sha512-aUdT6zEYtDKCaxkofmmJDJYGCf0+pJg3eU9/oBuqvEeoB9dKI6ZLc/1iLJCTuJQDO4ptntAlkUmHgGjyuobZbw==} 254 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 255 | cpu: [x64] 256 | os: [win32] 257 | 258 | '@next/env@15.3.3': 259 | resolution: {integrity: sha512-OdiMrzCl2Xi0VTjiQQUK0Xh7bJHnOuET2s+3V+Y40WJBAXrJeGA3f+I8MZJ/YQ3mVGi5XGR1L66oFlgqXhQ4Vw==} 260 | 261 | '@next/swc-darwin-arm64@15.3.3': 262 | resolution: {integrity: sha512-WRJERLuH+O3oYB4yZNVahSVFmtxRNjNF1I1c34tYMoJb0Pve+7/RaLAJJizyYiFhjYNGHRAE1Ri2Fd23zgDqhg==} 263 | engines: {node: '>= 10'} 264 | cpu: [arm64] 265 | os: [darwin] 266 | 267 | '@next/swc-darwin-x64@15.3.3': 268 | resolution: {integrity: sha512-XHdzH/yBc55lu78k/XwtuFR/ZXUTcflpRXcsu0nKmF45U96jt1tsOZhVrn5YH+paw66zOANpOnFQ9i6/j+UYvw==} 269 | engines: {node: '>= 10'} 270 | cpu: [x64] 271 | os: [darwin] 272 | 273 | '@next/swc-linux-arm64-gnu@15.3.3': 274 | resolution: {integrity: sha512-VZ3sYL2LXB8znNGcjhocikEkag/8xiLgnvQts41tq6i+wql63SMS1Q6N8RVXHw5pEUjiof+II3HkDd7GFcgkzw==} 275 | engines: {node: '>= 10'} 276 | cpu: [arm64] 277 | os: [linux] 278 | 279 | '@next/swc-linux-arm64-musl@15.3.3': 280 | resolution: {integrity: sha512-h6Y1fLU4RWAp1HPNJWDYBQ+e3G7sLckyBXhmH9ajn8l/RSMnhbuPBV/fXmy3muMcVwoJdHL+UtzRzs0nXOf9SA==} 281 | engines: {node: '>= 10'} 282 | cpu: [arm64] 283 | os: [linux] 284 | 285 | '@next/swc-linux-x64-gnu@15.3.3': 286 | resolution: {integrity: sha512-jJ8HRiF3N8Zw6hGlytCj5BiHyG/K+fnTKVDEKvUCyiQ/0r5tgwO7OgaRiOjjRoIx2vwLR+Rz8hQoPrnmFbJdfw==} 287 | engines: {node: '>= 10'} 288 | cpu: [x64] 289 | os: [linux] 290 | 291 | '@next/swc-linux-x64-musl@15.3.3': 292 | resolution: {integrity: sha512-HrUcTr4N+RgiiGn3jjeT6Oo208UT/7BuTr7K0mdKRBtTbT4v9zJqCDKO97DUqqoBK1qyzP1RwvrWTvU6EPh/Cw==} 293 | engines: {node: '>= 10'} 294 | cpu: [x64] 295 | os: [linux] 296 | 297 | '@next/swc-win32-arm64-msvc@15.3.3': 298 | resolution: {integrity: sha512-SxorONgi6K7ZUysMtRF3mIeHC5aA3IQLmKFQzU0OuhuUYwpOBc1ypaLJLP5Bf3M9k53KUUUj4vTPwzGvl/NwlQ==} 299 | engines: {node: '>= 10'} 300 | cpu: [arm64] 301 | os: [win32] 302 | 303 | '@next/swc-win32-x64-msvc@15.3.3': 304 | resolution: {integrity: sha512-4QZG6F8enl9/S2+yIiOiju0iCTFd93d8VC1q9LZS4p/Xuk81W2QDjCFeoogmrWWkAD59z8ZxepBQap2dKS5ruw==} 305 | engines: {node: '>= 10'} 306 | cpu: [x64] 307 | os: [win32] 308 | 309 | '@rvf/set-get@7.0.1': 310 | resolution: {integrity: sha512-GkTSn9K1GrTYoTUqlUs36k6nJnzjQaFBTTEIqUYmzBcsGsoJM8xG7EAx2WLHWAA4QzFjcwWUSHQ3vM3Fbw50Tg==} 311 | 312 | '@swc/counter@0.1.3': 313 | resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} 314 | 315 | '@swc/helpers@0.5.15': 316 | resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} 317 | 318 | '@tanstack/query-core@5.80.6': 319 | resolution: {integrity: sha512-nl7YxT/TAU+VTf+e2zTkObGTyY8YZBMnbgeA1ee66lIVqzKlYursAII6z5t0e6rXgwUMJSV4dshBTNacNpZHbQ==} 320 | 321 | '@tanstack/react-query@5.80.6': 322 | resolution: {integrity: sha512-izX+5CnkpON3NQGcEm3/d7LfFQNo9ZpFtX2QsINgCYK9LT2VCIdi8D3bMaMSNhrAJCznRoAkFic76uvLroALBw==} 323 | peerDependencies: 324 | react: ^18 || ^19 325 | 326 | '@trpc/client@11.0.0': 327 | resolution: {integrity: sha512-U2THlxsdr4ykAX5lpTU8k5WRADPQ+68Ex2gfUht3MlCxGK7njBmNSSzjpQSWNt7tMI/xsYrddFiRlmEPrh+Cbg==} 328 | peerDependencies: 329 | '@trpc/server': 11.0.0 330 | typescript: '>=5.7.2' 331 | 332 | '@trpc/next@11.0.0': 333 | resolution: {integrity: sha512-HpowgsF0jfXG30jEBVK8v90ltbEZiQZq/x0rsjScfZuedkAfapqZvrsrkzv6Pkemz7sxaxJcZB3HEqXxWfkGoA==} 334 | peerDependencies: 335 | '@tanstack/react-query': ^5.59.15 336 | '@trpc/client': 11.0.0 337 | '@trpc/react-query': 11.0.0 338 | '@trpc/server': 11.0.0 339 | next: '>=15.2.2' 340 | react: '>=16.8.0' 341 | react-dom: '>=16.8.0' 342 | typescript: '>=5.7.2' 343 | peerDependenciesMeta: 344 | '@tanstack/react-query': 345 | optional: true 346 | '@trpc/react-query': 347 | optional: true 348 | 349 | '@trpc/react-query@11.0.0': 350 | resolution: {integrity: sha512-HeE9bBLA6nqC2xk5wlNZIPQ5vmyli3tgNNab8fTE489+ksNMKxaIx66pZKsMJIorDcP1wS0rWNV+GroU0iR98g==} 351 | peerDependencies: 352 | '@tanstack/react-query': ^5.67.1 353 | '@trpc/client': 11.0.0 354 | '@trpc/server': 11.0.0 355 | react: '>=18.2.0' 356 | react-dom: '>=18.2.0' 357 | typescript: '>=5.7.2' 358 | 359 | '@trpc/server@11.0.0': 360 | resolution: {integrity: sha512-xY9q/b/wR/tWGYTm5xmRjivkYD2EZZXmOKmHuNJRYZuLbieeNUsdfQRjJC409WB1pjKWInomhHwuA8bahZJ4lQ==} 361 | peerDependencies: 362 | typescript: '>=5.7.2' 363 | 364 | '@types/estree@1.0.7': 365 | resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} 366 | 367 | '@types/json-schema@7.0.15': 368 | resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} 369 | 370 | '@types/node@22.15.30': 371 | resolution: {integrity: sha512-6Q7lr06bEHdlfplU6YRbgG1SFBdlsfNC4/lX+SkhiTs0cpJkOElmWls8PxDFv4yY/xKb8Y6SO0OmSX4wgqTZbA==} 372 | 373 | '@types/react-dom@19.1.6': 374 | resolution: {integrity: sha512-4hOiT/dwO8Ko0gV1m/TJZYk3y0KBnY9vzDh7W+DH17b2HFSOGgdj33dhihPeuy3l0q23+4e+hoXHV6hCC4dCXw==} 375 | peerDependencies: 376 | '@types/react': ^19.0.0 377 | 378 | '@types/react@19.1.6': 379 | resolution: {integrity: sha512-JeG0rEWak0N6Itr6QUx+X60uQmN+5t3j9r/OVDtWzFXKaj6kD1BwJzOksD0FF6iWxZlbE1kB0q9vtnU2ekqa1Q==} 380 | 381 | acorn-jsx@5.3.2: 382 | resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} 383 | peerDependencies: 384 | acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 385 | 386 | acorn@8.14.1: 387 | resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} 388 | engines: {node: '>=0.4.0'} 389 | hasBin: true 390 | 391 | ajv@6.12.6: 392 | resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} 393 | 394 | ansi-styles@4.3.0: 395 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} 396 | engines: {node: '>=8'} 397 | 398 | argparse@2.0.1: 399 | resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} 400 | 401 | balanced-match@1.0.2: 402 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 403 | 404 | brace-expansion@1.1.11: 405 | resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} 406 | 407 | busboy@1.6.0: 408 | resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} 409 | engines: {node: '>=10.16.0'} 410 | 411 | callsites@3.1.0: 412 | resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} 413 | engines: {node: '>=6'} 414 | 415 | caniuse-lite@1.0.30001721: 416 | resolution: {integrity: sha512-cOuvmUVtKrtEaoKiO0rSc29jcjwMwX5tOHDy4MgVFEWiUXj4uBMJkwI8MDySkgXidpMiHUcviogAvFi4pA2hDQ==} 417 | 418 | chalk@4.1.2: 419 | resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} 420 | engines: {node: '>=10'} 421 | 422 | client-only@0.0.1: 423 | resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} 424 | 425 | color-convert@2.0.1: 426 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} 427 | engines: {node: '>=7.0.0'} 428 | 429 | color-name@1.1.4: 430 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 431 | 432 | color-string@1.9.1: 433 | resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} 434 | 435 | color@4.2.3: 436 | resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} 437 | engines: {node: '>=12.5.0'} 438 | 439 | concat-map@0.0.1: 440 | resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} 441 | 442 | cross-spawn@7.0.6: 443 | resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} 444 | engines: {node: '>= 8'} 445 | 446 | csstype@3.1.3: 447 | resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} 448 | 449 | debug@4.4.1: 450 | resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} 451 | engines: {node: '>=6.0'} 452 | peerDependencies: 453 | supports-color: '*' 454 | peerDependenciesMeta: 455 | supports-color: 456 | optional: true 457 | 458 | deep-is@0.1.4: 459 | resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} 460 | 461 | detect-libc@2.0.4: 462 | resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} 463 | engines: {node: '>=8'} 464 | 465 | escape-string-regexp@4.0.0: 466 | resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} 467 | engines: {node: '>=10'} 468 | 469 | eslint-scope@8.3.0: 470 | resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==} 471 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 472 | 473 | eslint-visitor-keys@3.4.3: 474 | resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} 475 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 476 | 477 | eslint-visitor-keys@4.2.0: 478 | resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} 479 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 480 | 481 | eslint@9.28.0: 482 | resolution: {integrity: sha512-ocgh41VhRlf9+fVpe7QKzwLj9c92fDiqOj8Y3Sd4/ZmVA4Btx4PlUYPq4pp9JDyupkf1upbEXecxL2mwNV7jPQ==} 483 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 484 | hasBin: true 485 | peerDependencies: 486 | jiti: '*' 487 | peerDependenciesMeta: 488 | jiti: 489 | optional: true 490 | 491 | espree@10.3.0: 492 | resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} 493 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 494 | 495 | esquery@1.6.0: 496 | resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} 497 | engines: {node: '>=0.10'} 498 | 499 | esrecurse@4.3.0: 500 | resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} 501 | engines: {node: '>=4.0'} 502 | 503 | estraverse@5.3.0: 504 | resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} 505 | engines: {node: '>=4.0'} 506 | 507 | esutils@2.0.3: 508 | resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} 509 | engines: {node: '>=0.10.0'} 510 | 511 | fast-deep-equal@3.1.3: 512 | resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} 513 | 514 | fast-json-stable-stringify@2.1.0: 515 | resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} 516 | 517 | fast-levenshtein@2.0.6: 518 | resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} 519 | 520 | file-entry-cache@8.0.0: 521 | resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} 522 | engines: {node: '>=16.0.0'} 523 | 524 | find-up@5.0.0: 525 | resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} 526 | engines: {node: '>=10'} 527 | 528 | flat-cache@4.0.1: 529 | resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} 530 | engines: {node: '>=16'} 531 | 532 | flatted@3.3.3: 533 | resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} 534 | 535 | glob-parent@6.0.2: 536 | resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} 537 | engines: {node: '>=10.13.0'} 538 | 539 | globals@14.0.0: 540 | resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} 541 | engines: {node: '>=18'} 542 | 543 | has-flag@4.0.0: 544 | resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} 545 | engines: {node: '>=8'} 546 | 547 | ignore@5.3.2: 548 | resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} 549 | engines: {node: '>= 4'} 550 | 551 | import-fresh@3.3.1: 552 | resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} 553 | engines: {node: '>=6'} 554 | 555 | imurmurhash@0.1.4: 556 | resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} 557 | engines: {node: '>=0.8.19'} 558 | 559 | is-arrayish@0.3.2: 560 | resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} 561 | 562 | is-extglob@2.1.1: 563 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} 564 | engines: {node: '>=0.10.0'} 565 | 566 | is-glob@4.0.3: 567 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} 568 | engines: {node: '>=0.10.0'} 569 | 570 | isexe@2.0.0: 571 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} 572 | 573 | js-yaml@4.1.0: 574 | resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} 575 | hasBin: true 576 | 577 | json-buffer@3.0.1: 578 | resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} 579 | 580 | json-schema-traverse@0.4.1: 581 | resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} 582 | 583 | json-stable-stringify-without-jsonify@1.0.1: 584 | resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} 585 | 586 | keyv@4.5.4: 587 | resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} 588 | 589 | levn@0.4.1: 590 | resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} 591 | engines: {node: '>= 0.8.0'} 592 | 593 | locate-path@6.0.0: 594 | resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} 595 | engines: {node: '>=10'} 596 | 597 | lodash.merge@4.6.2: 598 | resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} 599 | 600 | minimatch@3.1.2: 601 | resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} 602 | 603 | ms@2.1.3: 604 | resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} 605 | 606 | nanoid@3.3.11: 607 | resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} 608 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 609 | hasBin: true 610 | 611 | natural-compare@1.4.0: 612 | resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} 613 | 614 | next@15.3.3: 615 | resolution: {integrity: sha512-JqNj29hHNmCLtNvd090SyRbXJiivQ+58XjCcrC50Crb5g5u2zi7Y2YivbsEfzk6AtVI80akdOQbaMZwWB1Hthw==} 616 | engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} 617 | hasBin: true 618 | peerDependencies: 619 | '@opentelemetry/api': ^1.1.0 620 | '@playwright/test': ^1.41.2 621 | babel-plugin-react-compiler: '*' 622 | react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 623 | react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 624 | sass: ^1.3.0 625 | peerDependenciesMeta: 626 | '@opentelemetry/api': 627 | optional: true 628 | '@playwright/test': 629 | optional: true 630 | babel-plugin-react-compiler: 631 | optional: true 632 | sass: 633 | optional: true 634 | 635 | optionator@0.9.4: 636 | resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} 637 | engines: {node: '>= 0.8.0'} 638 | 639 | p-limit@3.1.0: 640 | resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} 641 | engines: {node: '>=10'} 642 | 643 | p-locate@5.0.0: 644 | resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} 645 | engines: {node: '>=10'} 646 | 647 | parent-module@1.0.1: 648 | resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} 649 | engines: {node: '>=6'} 650 | 651 | path-exists@4.0.0: 652 | resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} 653 | engines: {node: '>=8'} 654 | 655 | path-key@3.1.1: 656 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} 657 | engines: {node: '>=8'} 658 | 659 | picocolors@1.1.1: 660 | resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} 661 | 662 | postcss@8.4.31: 663 | resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} 664 | engines: {node: ^10 || ^12 || >=14} 665 | 666 | prelude-ls@1.2.1: 667 | resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} 668 | engines: {node: '>= 0.8.0'} 669 | 670 | punycode@2.3.1: 671 | resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} 672 | engines: {node: '>=6'} 673 | 674 | react-dom@19.1.0: 675 | resolution: {integrity: sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==} 676 | peerDependencies: 677 | react: ^19.1.0 678 | 679 | react-hook-form@7.57.0: 680 | resolution: {integrity: sha512-RbEks3+cbvTP84l/VXGUZ+JMrKOS8ykQCRYdm5aYsxnDquL0vspsyNhGRO7pcH6hsZqWlPOjLye7rJqdtdAmlg==} 681 | engines: {node: '>=18.0.0'} 682 | peerDependencies: 683 | react: ^16.8.0 || ^17 || ^18 || ^19 684 | 685 | react@19.1.0: 686 | resolution: {integrity: sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==} 687 | engines: {node: '>=0.10.0'} 688 | 689 | resolve-from@4.0.0: 690 | resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} 691 | engines: {node: '>=4'} 692 | 693 | scheduler@0.26.0: 694 | resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} 695 | 696 | semver@7.7.2: 697 | resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} 698 | engines: {node: '>=10'} 699 | hasBin: true 700 | 701 | sharp@0.34.2: 702 | resolution: {integrity: sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==} 703 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 704 | 705 | shebang-command@2.0.0: 706 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} 707 | engines: {node: '>=8'} 708 | 709 | shebang-regex@3.0.0: 710 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} 711 | engines: {node: '>=8'} 712 | 713 | simple-swizzle@0.2.2: 714 | resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} 715 | 716 | source-map-js@1.2.1: 717 | resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} 718 | engines: {node: '>=0.10.0'} 719 | 720 | streamsearch@1.1.0: 721 | resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} 722 | engines: {node: '>=10.0.0'} 723 | 724 | strip-json-comments@3.1.1: 725 | resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} 726 | engines: {node: '>=8'} 727 | 728 | styled-jsx@5.1.6: 729 | resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} 730 | engines: {node: '>= 12.0.0'} 731 | peerDependencies: 732 | '@babel/core': '*' 733 | babel-plugin-macros: '*' 734 | react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' 735 | peerDependenciesMeta: 736 | '@babel/core': 737 | optional: true 738 | babel-plugin-macros: 739 | optional: true 740 | 741 | supports-color@7.2.0: 742 | resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} 743 | engines: {node: '>=8'} 744 | 745 | tslib@2.8.1: 746 | resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} 747 | 748 | type-check@0.4.0: 749 | resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} 750 | engines: {node: '>= 0.8.0'} 751 | 752 | typescript@5.8.3: 753 | resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} 754 | engines: {node: '>=14.17'} 755 | hasBin: true 756 | 757 | undici-types@6.21.0: 758 | resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} 759 | 760 | uri-js@4.4.1: 761 | resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} 762 | 763 | which@2.0.2: 764 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} 765 | engines: {node: '>= 8'} 766 | hasBin: true 767 | 768 | word-wrap@1.2.5: 769 | resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} 770 | engines: {node: '>=0.10.0'} 771 | 772 | yocto-queue@0.1.0: 773 | resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} 774 | engines: {node: '>=10'} 775 | 776 | zod-form-data@2.0.7: 777 | resolution: {integrity: sha512-O27uzKMx7qc7z51KXER326Fp966jqHGvZX3i18CbvElF/QqVsQQN6Q7BnzepkzeBzTJnU3golibVSagf4dp7RQ==} 778 | peerDependencies: 779 | zod: '>= 3.11.0' 780 | 781 | zod@3.25.51: 782 | resolution: {integrity: sha512-TQSnBldh+XSGL+opiSIq0575wvDPqu09AqWe1F7JhUMKY+M91/aGlK4MhpVNO7MgYfHcVCB1ffwAUTJzllKJqg==} 783 | 784 | snapshots: 785 | 786 | '@emnapi/runtime@1.4.3': 787 | dependencies: 788 | tslib: 2.8.1 789 | optional: true 790 | 791 | '@eslint-community/eslint-utils@4.7.0(eslint@9.28.0)': 792 | dependencies: 793 | eslint: 9.28.0 794 | eslint-visitor-keys: 3.4.3 795 | 796 | '@eslint-community/regexpp@4.12.1': {} 797 | 798 | '@eslint/config-array@0.20.0': 799 | dependencies: 800 | '@eslint/object-schema': 2.1.6 801 | debug: 4.4.1 802 | minimatch: 3.1.2 803 | transitivePeerDependencies: 804 | - supports-color 805 | 806 | '@eslint/config-helpers@0.2.2': {} 807 | 808 | '@eslint/core@0.14.0': 809 | dependencies: 810 | '@types/json-schema': 7.0.15 811 | 812 | '@eslint/eslintrc@3.3.1': 813 | dependencies: 814 | ajv: 6.12.6 815 | debug: 4.4.1 816 | espree: 10.3.0 817 | globals: 14.0.0 818 | ignore: 5.3.2 819 | import-fresh: 3.3.1 820 | js-yaml: 4.1.0 821 | minimatch: 3.1.2 822 | strip-json-comments: 3.1.1 823 | transitivePeerDependencies: 824 | - supports-color 825 | 826 | '@eslint/js@9.28.0': {} 827 | 828 | '@eslint/object-schema@2.1.6': {} 829 | 830 | '@eslint/plugin-kit@0.3.1': 831 | dependencies: 832 | '@eslint/core': 0.14.0 833 | levn: 0.4.1 834 | 835 | '@hookform/error-message@2.0.1(react-dom@19.1.0(react@19.1.0))(react-hook-form@7.57.0(react@19.1.0))(react@19.1.0)': 836 | dependencies: 837 | react: 19.1.0 838 | react-dom: 19.1.0(react@19.1.0) 839 | react-hook-form: 7.57.0(react@19.1.0) 840 | 841 | '@hookform/resolvers@3.10.0(react-hook-form@7.57.0(react@19.1.0))': 842 | dependencies: 843 | react-hook-form: 7.57.0(react@19.1.0) 844 | 845 | '@humanfs/core@0.19.1': {} 846 | 847 | '@humanfs/node@0.16.6': 848 | dependencies: 849 | '@humanfs/core': 0.19.1 850 | '@humanwhocodes/retry': 0.3.1 851 | 852 | '@humanwhocodes/module-importer@1.0.1': {} 853 | 854 | '@humanwhocodes/retry@0.3.1': {} 855 | 856 | '@humanwhocodes/retry@0.4.3': {} 857 | 858 | '@img/sharp-darwin-arm64@0.34.2': 859 | optionalDependencies: 860 | '@img/sharp-libvips-darwin-arm64': 1.1.0 861 | optional: true 862 | 863 | '@img/sharp-darwin-x64@0.34.2': 864 | optionalDependencies: 865 | '@img/sharp-libvips-darwin-x64': 1.1.0 866 | optional: true 867 | 868 | '@img/sharp-libvips-darwin-arm64@1.1.0': 869 | optional: true 870 | 871 | '@img/sharp-libvips-darwin-x64@1.1.0': 872 | optional: true 873 | 874 | '@img/sharp-libvips-linux-arm64@1.1.0': 875 | optional: true 876 | 877 | '@img/sharp-libvips-linux-arm@1.1.0': 878 | optional: true 879 | 880 | '@img/sharp-libvips-linux-ppc64@1.1.0': 881 | optional: true 882 | 883 | '@img/sharp-libvips-linux-s390x@1.1.0': 884 | optional: true 885 | 886 | '@img/sharp-libvips-linux-x64@1.1.0': 887 | optional: true 888 | 889 | '@img/sharp-libvips-linuxmusl-arm64@1.1.0': 890 | optional: true 891 | 892 | '@img/sharp-libvips-linuxmusl-x64@1.1.0': 893 | optional: true 894 | 895 | '@img/sharp-linux-arm64@0.34.2': 896 | optionalDependencies: 897 | '@img/sharp-libvips-linux-arm64': 1.1.0 898 | optional: true 899 | 900 | '@img/sharp-linux-arm@0.34.2': 901 | optionalDependencies: 902 | '@img/sharp-libvips-linux-arm': 1.1.0 903 | optional: true 904 | 905 | '@img/sharp-linux-s390x@0.34.2': 906 | optionalDependencies: 907 | '@img/sharp-libvips-linux-s390x': 1.1.0 908 | optional: true 909 | 910 | '@img/sharp-linux-x64@0.34.2': 911 | optionalDependencies: 912 | '@img/sharp-libvips-linux-x64': 1.1.0 913 | optional: true 914 | 915 | '@img/sharp-linuxmusl-arm64@0.34.2': 916 | optionalDependencies: 917 | '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 918 | optional: true 919 | 920 | '@img/sharp-linuxmusl-x64@0.34.2': 921 | optionalDependencies: 922 | '@img/sharp-libvips-linuxmusl-x64': 1.1.0 923 | optional: true 924 | 925 | '@img/sharp-wasm32@0.34.2': 926 | dependencies: 927 | '@emnapi/runtime': 1.4.3 928 | optional: true 929 | 930 | '@img/sharp-win32-arm64@0.34.2': 931 | optional: true 932 | 933 | '@img/sharp-win32-ia32@0.34.2': 934 | optional: true 935 | 936 | '@img/sharp-win32-x64@0.34.2': 937 | optional: true 938 | 939 | '@next/env@15.3.3': {} 940 | 941 | '@next/swc-darwin-arm64@15.3.3': 942 | optional: true 943 | 944 | '@next/swc-darwin-x64@15.3.3': 945 | optional: true 946 | 947 | '@next/swc-linux-arm64-gnu@15.3.3': 948 | optional: true 949 | 950 | '@next/swc-linux-arm64-musl@15.3.3': 951 | optional: true 952 | 953 | '@next/swc-linux-x64-gnu@15.3.3': 954 | optional: true 955 | 956 | '@next/swc-linux-x64-musl@15.3.3': 957 | optional: true 958 | 959 | '@next/swc-win32-arm64-msvc@15.3.3': 960 | optional: true 961 | 962 | '@next/swc-win32-x64-msvc@15.3.3': 963 | optional: true 964 | 965 | '@rvf/set-get@7.0.1': {} 966 | 967 | '@swc/counter@0.1.3': {} 968 | 969 | '@swc/helpers@0.5.15': 970 | dependencies: 971 | tslib: 2.8.1 972 | 973 | '@tanstack/query-core@5.80.6': {} 974 | 975 | '@tanstack/react-query@5.80.6(react@19.1.0)': 976 | dependencies: 977 | '@tanstack/query-core': 5.80.6 978 | react: 19.1.0 979 | 980 | '@trpc/client@11.0.0(@trpc/server@11.0.0(typescript@5.8.3))(typescript@5.8.3)': 981 | dependencies: 982 | '@trpc/server': 11.0.0(typescript@5.8.3) 983 | typescript: 5.8.3 984 | 985 | '@trpc/next@11.0.0(@tanstack/react-query@5.80.6(react@19.1.0))(@trpc/client@11.0.0(@trpc/server@11.0.0(typescript@5.8.3))(typescript@5.8.3))(@trpc/react-query@11.0.0(@tanstack/react-query@5.80.6(react@19.1.0))(@trpc/client@11.0.0(@trpc/server@11.0.0(typescript@5.8.3))(typescript@5.8.3))(@trpc/server@11.0.0(typescript@5.8.3))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.8.3))(@trpc/server@11.0.0(typescript@5.8.3))(next@15.3.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.8.3)': 986 | dependencies: 987 | '@trpc/client': 11.0.0(@trpc/server@11.0.0(typescript@5.8.3))(typescript@5.8.3) 988 | '@trpc/server': 11.0.0(typescript@5.8.3) 989 | next: 15.3.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0) 990 | react: 19.1.0 991 | react-dom: 19.1.0(react@19.1.0) 992 | typescript: 5.8.3 993 | optionalDependencies: 994 | '@tanstack/react-query': 5.80.6(react@19.1.0) 995 | '@trpc/react-query': 11.0.0(@tanstack/react-query@5.80.6(react@19.1.0))(@trpc/client@11.0.0(@trpc/server@11.0.0(typescript@5.8.3))(typescript@5.8.3))(@trpc/server@11.0.0(typescript@5.8.3))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.8.3) 996 | 997 | '@trpc/react-query@11.0.0(@tanstack/react-query@5.80.6(react@19.1.0))(@trpc/client@11.0.0(@trpc/server@11.0.0(typescript@5.8.3))(typescript@5.8.3))(@trpc/server@11.0.0(typescript@5.8.3))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.8.3)': 998 | dependencies: 999 | '@tanstack/react-query': 5.80.6(react@19.1.0) 1000 | '@trpc/client': 11.0.0(@trpc/server@11.0.0(typescript@5.8.3))(typescript@5.8.3) 1001 | '@trpc/server': 11.0.0(typescript@5.8.3) 1002 | react: 19.1.0 1003 | react-dom: 19.1.0(react@19.1.0) 1004 | typescript: 5.8.3 1005 | 1006 | '@trpc/server@11.0.0(typescript@5.8.3)': 1007 | dependencies: 1008 | typescript: 5.8.3 1009 | 1010 | '@types/estree@1.0.7': {} 1011 | 1012 | '@types/json-schema@7.0.15': {} 1013 | 1014 | '@types/node@22.15.30': 1015 | dependencies: 1016 | undici-types: 6.21.0 1017 | 1018 | '@types/react-dom@19.1.6(@types/react@19.1.6)': 1019 | dependencies: 1020 | '@types/react': 19.1.6 1021 | 1022 | '@types/react@19.1.6': 1023 | dependencies: 1024 | csstype: 3.1.3 1025 | 1026 | acorn-jsx@5.3.2(acorn@8.14.1): 1027 | dependencies: 1028 | acorn: 8.14.1 1029 | 1030 | acorn@8.14.1: {} 1031 | 1032 | ajv@6.12.6: 1033 | dependencies: 1034 | fast-deep-equal: 3.1.3 1035 | fast-json-stable-stringify: 2.1.0 1036 | json-schema-traverse: 0.4.1 1037 | uri-js: 4.4.1 1038 | 1039 | ansi-styles@4.3.0: 1040 | dependencies: 1041 | color-convert: 2.0.1 1042 | 1043 | argparse@2.0.1: {} 1044 | 1045 | balanced-match@1.0.2: {} 1046 | 1047 | brace-expansion@1.1.11: 1048 | dependencies: 1049 | balanced-match: 1.0.2 1050 | concat-map: 0.0.1 1051 | 1052 | busboy@1.6.0: 1053 | dependencies: 1054 | streamsearch: 1.1.0 1055 | 1056 | callsites@3.1.0: {} 1057 | 1058 | caniuse-lite@1.0.30001721: {} 1059 | 1060 | chalk@4.1.2: 1061 | dependencies: 1062 | ansi-styles: 4.3.0 1063 | supports-color: 7.2.0 1064 | 1065 | client-only@0.0.1: {} 1066 | 1067 | color-convert@2.0.1: 1068 | dependencies: 1069 | color-name: 1.1.4 1070 | 1071 | color-name@1.1.4: {} 1072 | 1073 | color-string@1.9.1: 1074 | dependencies: 1075 | color-name: 1.1.4 1076 | simple-swizzle: 0.2.2 1077 | optional: true 1078 | 1079 | color@4.2.3: 1080 | dependencies: 1081 | color-convert: 2.0.1 1082 | color-string: 1.9.1 1083 | optional: true 1084 | 1085 | concat-map@0.0.1: {} 1086 | 1087 | cross-spawn@7.0.6: 1088 | dependencies: 1089 | path-key: 3.1.1 1090 | shebang-command: 2.0.0 1091 | which: 2.0.2 1092 | 1093 | csstype@3.1.3: {} 1094 | 1095 | debug@4.4.1: 1096 | dependencies: 1097 | ms: 2.1.3 1098 | 1099 | deep-is@0.1.4: {} 1100 | 1101 | detect-libc@2.0.4: 1102 | optional: true 1103 | 1104 | escape-string-regexp@4.0.0: {} 1105 | 1106 | eslint-scope@8.3.0: 1107 | dependencies: 1108 | esrecurse: 4.3.0 1109 | estraverse: 5.3.0 1110 | 1111 | eslint-visitor-keys@3.4.3: {} 1112 | 1113 | eslint-visitor-keys@4.2.0: {} 1114 | 1115 | eslint@9.28.0: 1116 | dependencies: 1117 | '@eslint-community/eslint-utils': 4.7.0(eslint@9.28.0) 1118 | '@eslint-community/regexpp': 4.12.1 1119 | '@eslint/config-array': 0.20.0 1120 | '@eslint/config-helpers': 0.2.2 1121 | '@eslint/core': 0.14.0 1122 | '@eslint/eslintrc': 3.3.1 1123 | '@eslint/js': 9.28.0 1124 | '@eslint/plugin-kit': 0.3.1 1125 | '@humanfs/node': 0.16.6 1126 | '@humanwhocodes/module-importer': 1.0.1 1127 | '@humanwhocodes/retry': 0.4.3 1128 | '@types/estree': 1.0.7 1129 | '@types/json-schema': 7.0.15 1130 | ajv: 6.12.6 1131 | chalk: 4.1.2 1132 | cross-spawn: 7.0.6 1133 | debug: 4.4.1 1134 | escape-string-regexp: 4.0.0 1135 | eslint-scope: 8.3.0 1136 | eslint-visitor-keys: 4.2.0 1137 | espree: 10.3.0 1138 | esquery: 1.6.0 1139 | esutils: 2.0.3 1140 | fast-deep-equal: 3.1.3 1141 | file-entry-cache: 8.0.0 1142 | find-up: 5.0.0 1143 | glob-parent: 6.0.2 1144 | ignore: 5.3.2 1145 | imurmurhash: 0.1.4 1146 | is-glob: 4.0.3 1147 | json-stable-stringify-without-jsonify: 1.0.1 1148 | lodash.merge: 4.6.2 1149 | minimatch: 3.1.2 1150 | natural-compare: 1.4.0 1151 | optionator: 0.9.4 1152 | transitivePeerDependencies: 1153 | - supports-color 1154 | 1155 | espree@10.3.0: 1156 | dependencies: 1157 | acorn: 8.14.1 1158 | acorn-jsx: 5.3.2(acorn@8.14.1) 1159 | eslint-visitor-keys: 4.2.0 1160 | 1161 | esquery@1.6.0: 1162 | dependencies: 1163 | estraverse: 5.3.0 1164 | 1165 | esrecurse@4.3.0: 1166 | dependencies: 1167 | estraverse: 5.3.0 1168 | 1169 | estraverse@5.3.0: {} 1170 | 1171 | esutils@2.0.3: {} 1172 | 1173 | fast-deep-equal@3.1.3: {} 1174 | 1175 | fast-json-stable-stringify@2.1.0: {} 1176 | 1177 | fast-levenshtein@2.0.6: {} 1178 | 1179 | file-entry-cache@8.0.0: 1180 | dependencies: 1181 | flat-cache: 4.0.1 1182 | 1183 | find-up@5.0.0: 1184 | dependencies: 1185 | locate-path: 6.0.0 1186 | path-exists: 4.0.0 1187 | 1188 | flat-cache@4.0.1: 1189 | dependencies: 1190 | flatted: 3.3.3 1191 | keyv: 4.5.4 1192 | 1193 | flatted@3.3.3: {} 1194 | 1195 | glob-parent@6.0.2: 1196 | dependencies: 1197 | is-glob: 4.0.3 1198 | 1199 | globals@14.0.0: {} 1200 | 1201 | has-flag@4.0.0: {} 1202 | 1203 | ignore@5.3.2: {} 1204 | 1205 | import-fresh@3.3.1: 1206 | dependencies: 1207 | parent-module: 1.0.1 1208 | resolve-from: 4.0.0 1209 | 1210 | imurmurhash@0.1.4: {} 1211 | 1212 | is-arrayish@0.3.2: 1213 | optional: true 1214 | 1215 | is-extglob@2.1.1: {} 1216 | 1217 | is-glob@4.0.3: 1218 | dependencies: 1219 | is-extglob: 2.1.1 1220 | 1221 | isexe@2.0.0: {} 1222 | 1223 | js-yaml@4.1.0: 1224 | dependencies: 1225 | argparse: 2.0.1 1226 | 1227 | json-buffer@3.0.1: {} 1228 | 1229 | json-schema-traverse@0.4.1: {} 1230 | 1231 | json-stable-stringify-without-jsonify@1.0.1: {} 1232 | 1233 | keyv@4.5.4: 1234 | dependencies: 1235 | json-buffer: 3.0.1 1236 | 1237 | levn@0.4.1: 1238 | dependencies: 1239 | prelude-ls: 1.2.1 1240 | type-check: 0.4.0 1241 | 1242 | locate-path@6.0.0: 1243 | dependencies: 1244 | p-locate: 5.0.0 1245 | 1246 | lodash.merge@4.6.2: {} 1247 | 1248 | minimatch@3.1.2: 1249 | dependencies: 1250 | brace-expansion: 1.1.11 1251 | 1252 | ms@2.1.3: {} 1253 | 1254 | nanoid@3.3.11: {} 1255 | 1256 | natural-compare@1.4.0: {} 1257 | 1258 | next@15.3.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0): 1259 | dependencies: 1260 | '@next/env': 15.3.3 1261 | '@swc/counter': 0.1.3 1262 | '@swc/helpers': 0.5.15 1263 | busboy: 1.6.0 1264 | caniuse-lite: 1.0.30001721 1265 | postcss: 8.4.31 1266 | react: 19.1.0 1267 | react-dom: 19.1.0(react@19.1.0) 1268 | styled-jsx: 5.1.6(react@19.1.0) 1269 | optionalDependencies: 1270 | '@next/swc-darwin-arm64': 15.3.3 1271 | '@next/swc-darwin-x64': 15.3.3 1272 | '@next/swc-linux-arm64-gnu': 15.3.3 1273 | '@next/swc-linux-arm64-musl': 15.3.3 1274 | '@next/swc-linux-x64-gnu': 15.3.3 1275 | '@next/swc-linux-x64-musl': 15.3.3 1276 | '@next/swc-win32-arm64-msvc': 15.3.3 1277 | '@next/swc-win32-x64-msvc': 15.3.3 1278 | sharp: 0.34.2 1279 | transitivePeerDependencies: 1280 | - '@babel/core' 1281 | - babel-plugin-macros 1282 | 1283 | optionator@0.9.4: 1284 | dependencies: 1285 | deep-is: 0.1.4 1286 | fast-levenshtein: 2.0.6 1287 | levn: 0.4.1 1288 | prelude-ls: 1.2.1 1289 | type-check: 0.4.0 1290 | word-wrap: 1.2.5 1291 | 1292 | p-limit@3.1.0: 1293 | dependencies: 1294 | yocto-queue: 0.1.0 1295 | 1296 | p-locate@5.0.0: 1297 | dependencies: 1298 | p-limit: 3.1.0 1299 | 1300 | parent-module@1.0.1: 1301 | dependencies: 1302 | callsites: 3.1.0 1303 | 1304 | path-exists@4.0.0: {} 1305 | 1306 | path-key@3.1.1: {} 1307 | 1308 | picocolors@1.1.1: {} 1309 | 1310 | postcss@8.4.31: 1311 | dependencies: 1312 | nanoid: 3.3.11 1313 | picocolors: 1.1.1 1314 | source-map-js: 1.2.1 1315 | 1316 | prelude-ls@1.2.1: {} 1317 | 1318 | punycode@2.3.1: {} 1319 | 1320 | react-dom@19.1.0(react@19.1.0): 1321 | dependencies: 1322 | react: 19.1.0 1323 | scheduler: 0.26.0 1324 | 1325 | react-hook-form@7.57.0(react@19.1.0): 1326 | dependencies: 1327 | react: 19.1.0 1328 | 1329 | react@19.1.0: {} 1330 | 1331 | resolve-from@4.0.0: {} 1332 | 1333 | scheduler@0.26.0: {} 1334 | 1335 | semver@7.7.2: 1336 | optional: true 1337 | 1338 | sharp@0.34.2: 1339 | dependencies: 1340 | color: 4.2.3 1341 | detect-libc: 2.0.4 1342 | semver: 7.7.2 1343 | optionalDependencies: 1344 | '@img/sharp-darwin-arm64': 0.34.2 1345 | '@img/sharp-darwin-x64': 0.34.2 1346 | '@img/sharp-libvips-darwin-arm64': 1.1.0 1347 | '@img/sharp-libvips-darwin-x64': 1.1.0 1348 | '@img/sharp-libvips-linux-arm': 1.1.0 1349 | '@img/sharp-libvips-linux-arm64': 1.1.0 1350 | '@img/sharp-libvips-linux-ppc64': 1.1.0 1351 | '@img/sharp-libvips-linux-s390x': 1.1.0 1352 | '@img/sharp-libvips-linux-x64': 1.1.0 1353 | '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 1354 | '@img/sharp-libvips-linuxmusl-x64': 1.1.0 1355 | '@img/sharp-linux-arm': 0.34.2 1356 | '@img/sharp-linux-arm64': 0.34.2 1357 | '@img/sharp-linux-s390x': 0.34.2 1358 | '@img/sharp-linux-x64': 0.34.2 1359 | '@img/sharp-linuxmusl-arm64': 0.34.2 1360 | '@img/sharp-linuxmusl-x64': 0.34.2 1361 | '@img/sharp-wasm32': 0.34.2 1362 | '@img/sharp-win32-arm64': 0.34.2 1363 | '@img/sharp-win32-ia32': 0.34.2 1364 | '@img/sharp-win32-x64': 0.34.2 1365 | optional: true 1366 | 1367 | shebang-command@2.0.0: 1368 | dependencies: 1369 | shebang-regex: 3.0.0 1370 | 1371 | shebang-regex@3.0.0: {} 1372 | 1373 | simple-swizzle@0.2.2: 1374 | dependencies: 1375 | is-arrayish: 0.3.2 1376 | optional: true 1377 | 1378 | source-map-js@1.2.1: {} 1379 | 1380 | streamsearch@1.1.0: {} 1381 | 1382 | strip-json-comments@3.1.1: {} 1383 | 1384 | styled-jsx@5.1.6(react@19.1.0): 1385 | dependencies: 1386 | client-only: 0.0.1 1387 | react: 19.1.0 1388 | 1389 | supports-color@7.2.0: 1390 | dependencies: 1391 | has-flag: 4.0.0 1392 | 1393 | tslib@2.8.1: {} 1394 | 1395 | type-check@0.4.0: 1396 | dependencies: 1397 | prelude-ls: 1.2.1 1398 | 1399 | typescript@5.8.3: {} 1400 | 1401 | undici-types@6.21.0: {} 1402 | 1403 | uri-js@4.4.1: 1404 | dependencies: 1405 | punycode: 2.3.1 1406 | 1407 | which@2.0.2: 1408 | dependencies: 1409 | isexe: 2.0.0 1410 | 1411 | word-wrap@1.2.5: {} 1412 | 1413 | yocto-queue@0.1.0: {} 1414 | 1415 | zod-form-data@2.0.7(zod@3.25.51): 1416 | dependencies: 1417 | '@rvf/set-get': 7.0.1 1418 | zod: 3.25.51 1419 | 1420 | zod@3.25.51: {} 1421 | -------------------------------------------------------------------------------- /src/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import type { AppType } from 'next/app'; 2 | import { trpc } from '../utils/trpc'; 3 | 4 | const MyApp: AppType = ({ Component, pageProps }) => { 5 | return ; 6 | }; 7 | 8 | export default trpc.withTRPC(MyApp); 9 | -------------------------------------------------------------------------------- /src/pages/api/trpc/[trpc].ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This is the API-handler of your app that contains all your API routes. 3 | * On a bigger app, you will probably want to split this file up into multiple files. 4 | */ 5 | import * as trpcNext from '@trpc/server/adapters/next'; 6 | import { roomRouter } from '~/server/routers/room'; 7 | import { createContext, router } from '~/server/trpc'; 8 | import type { NextApiRequest, NextApiResponse } from 'next'; 9 | 10 | const appRouter = router({ 11 | room: roomRouter, 12 | }); 13 | 14 | // export only the type definition of the API 15 | // None of the actual implementation is exposed to the client 16 | export type AppRouter = typeof appRouter; 17 | 18 | const handler = trpcNext.createNextApiHandler({ 19 | router: appRouter, 20 | createContext, 21 | }); 22 | // export API handler 23 | export default async (req: NextApiRequest, res: NextApiResponse) => { 24 | await handler(req, res); 25 | }; 26 | 27 | export const config = { 28 | api: { 29 | bodyParser: false, 30 | responseLimit: '100mb', 31 | }, 32 | }; 33 | -------------------------------------------------------------------------------- /src/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import Link from 'next/link'; 2 | 3 | export default function IndexPage() { 4 | return ( 5 |
    6 |
  • 7 | /vanilla 8 |
  • 9 |
  • 10 | /react-hook-form 11 |
  • 12 |
13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /src/pages/react-hook-form.tsx: -------------------------------------------------------------------------------- 1 | import { zodResolver } from '@hookform/resolvers/zod'; 2 | import { uploadFileSchema } from '~/utils/schemas'; 3 | import { trpc } from '~/utils/trpc'; 4 | import { useRef, useState } from 'react'; 5 | import type { UseFormProps } from 'react-hook-form'; 6 | import { FormProvider, useForm } from 'react-hook-form'; 7 | import type { z } from 'zod'; 8 | 9 | /** 10 | * zod-form-data wraps zod in an effect where the original type is a `FormData` 11 | */ 12 | type UnwrapZodEffect = 13 | TType extends z.ZodEffects ? U : TType; 14 | 15 | type GetInput = UnwrapZodEffect['_input']; 16 | 17 | function useZodFormData( 18 | props: Omit>, 'resolver'> & { 19 | schema: TSchema; 20 | }, 21 | ) { 22 | const formRef = useRef(null); 23 | const _resolver = zodResolver(props.schema, undefined, { 24 | raw: true, 25 | }); 26 | 27 | const form = useForm>({ 28 | ...props, 29 | resolver: (_, ctx, opts) => { 30 | if (!formRef.current) { 31 | return { 32 | values: {}, 33 | errors: { 34 | root: { 35 | message: 'Form not mounted', 36 | }, 37 | }, 38 | }; 39 | } 40 | const values = new FormData(formRef.current); 41 | return _resolver(values, ctx, opts); 42 | }, 43 | }); 44 | 45 | return { ...form, formRef }; 46 | } 47 | 48 | export default function Page() { 49 | const mutation = trpc.room.sendMessage.useMutation({ 50 | onError(err) { 51 | alert('Error from server: ' + err.message); 52 | }, 53 | }); 54 | 55 | const form = useZodFormData({ 56 | schema: uploadFileSchema, 57 | defaultValues: { 58 | name: 'whadaaaap', 59 | }, 60 | }); 61 | 62 | const [noJs, setNoJs] = useState(false); 63 | 64 | return ( 65 | <> 66 |

Posts

67 | 68 | 69 |
{ 74 | if (noJs) { 75 | return; 76 | } 77 | void form.handleSubmit(async (values, event) => { 78 | await mutation.mutateAsync(new FormData(event?.target)); 79 | })(_event); 80 | }} 81 | style={{ display: 'flex', flexDirection: 'column', gap: 10 }} 82 | ref={form.formRef} 83 | > 84 |
85 | Form with file upload 86 |
87 | 88 | 89 | {form.formState.errors.name && ( 90 |
{form.formState.errors.name.message}
91 | )} 92 |
93 | 94 |
95 | 96 | 97 | {form.formState.errors.image && ( 98 |
{form.formState.errors.image.message}
99 | )} 100 |
101 | 102 |
103 | 104 | { 108 | setNoJs(e.target.checked); 109 | }} 110 | /> 111 |
112 |
113 | 116 |
117 |
118 |
119 | 120 | {mutation.data && ( 121 |
122 | Upload result 123 |
    124 |
  • 125 | Image:
    126 | {mutation.data.image.url} 130 |
  • 131 |
132 |
133 | )} 134 |
135 | 136 | ); 137 | } 138 | -------------------------------------------------------------------------------- /src/pages/vanilla.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * This is a Next.js page. 3 | */ 4 | import { trpc } from '../utils/trpc'; 5 | 6 | export default function IndexPage() { 7 | const mutation = trpc.room.sendMessage.useMutation({ 8 | onSuccess() { 9 | alert('success!'); 10 | }, 11 | onError(err) { 12 | alert('Error: ' + err.message); 13 | }, 14 | }); 15 | 16 | return ( 17 | <> 18 | {/** 19 | * The type is defined and can be autocompleted 20 | * 💡 Tip: Hover over `data` to see the result type 21 | * 💡 Tip: CMD+Click (or CTRL+Click) on `text` to go to the server definition 22 | * 💡 Tip: Secondary click on `text` and "Rename Symbol" to rename it both on the client & server 23 | */} 24 |

Form!

25 |
26 | Form with file upload 27 |
{ 32 | const formData = new FormData(e.currentTarget); 33 | if (formData.get('nojs')) { 34 | // Submit the form the oldschool way 35 | return; 36 | } 37 | 38 | mutation.mutate(formData); 39 | e.preventDefault(); 40 | }} 41 | > 42 |

43 | 44 |

45 |

46 | 47 |

48 | 49 |

50 | {' '} 51 | 52 |

53 |

54 | 55 |

56 |
57 |
58 | 59 | {mutation.data && ( 60 |
61 | Upload result 62 |
    63 |
  • 64 | Image:
    65 | {mutation.data.image.url} 69 |
  • 70 |
71 |
72 | )} 73 | 74 | ); 75 | } 76 | -------------------------------------------------------------------------------- /src/server/routers/room.ts: -------------------------------------------------------------------------------- 1 | import { uploadFileSchema } from '~/utils/schemas'; 2 | import { writeFileToDisk } from '../../utils/writeFileToDisk'; 3 | import { publicProcedure, router } from '../trpc'; 4 | 5 | export const roomRouter = router({ 6 | sendMessage: publicProcedure 7 | .input(uploadFileSchema) 8 | .mutation(async (opts) => { 9 | return { 10 | image: await writeFileToDisk(opts.input.image), 11 | }; 12 | }), 13 | }); 14 | -------------------------------------------------------------------------------- /src/server/routers/viewer.ts: -------------------------------------------------------------------------------- 1 | import { uploadFileSchema } from '~/utils/schemas'; 2 | import { writeFileToDisk } from '~/utils/writeFileToDisk'; 3 | import { z } from 'zod'; 4 | import { publicProcedure, router } from '../trpc'; 5 | 6 | export const viewer = router({ 7 | updateProfile: publicProcedure 8 | .input( 9 | z.object({ 10 | formData: uploadFileSchema, 11 | }), 12 | ) 13 | .mutation(async (opts) => { 14 | return { 15 | name: opts.input.formData.name, 16 | image: await writeFileToDisk(opts.input.formData.image), 17 | }; 18 | }), 19 | }); 20 | -------------------------------------------------------------------------------- /src/server/trpc.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This is your entry point to setup the root configuration for tRPC on the server. 3 | * - `initTRPC` should only be used once per app. 4 | * - We export only the functionality that we use so we can enforce which base procedures should be used 5 | * 6 | * Learn how to create protected base procedures and other things below: 7 | * @see https://trpc.io/docs/v11/router 8 | * @see https://trpc.io/docs/v11/procedures 9 | */ 10 | import { initTRPC } from '@trpc/server'; 11 | import type * as trpcNext from '@trpc/server/adapters/next'; 12 | import { ZodError } from 'zod'; 13 | 14 | /** 15 | * Creates context for an incoming request 16 | * @see https://trpc.io/docs/v11/context 17 | */ 18 | export async function createContext(opts: trpcNext.CreateNextContextOptions) { 19 | return { 20 | req: opts.req, 21 | }; 22 | } 23 | 24 | export type Context = Awaited>; 25 | 26 | const t = initTRPC.context().create({ 27 | errorFormatter(opts) { 28 | return { 29 | ...opts.shape, 30 | data: { 31 | zodError: 32 | opts.error.code === 'BAD_REQUEST' && 33 | opts.error.cause instanceof ZodError 34 | ? opts.error.cause.flatten() 35 | : null, 36 | ...opts.shape.data, 37 | }, 38 | }; 39 | }, 40 | }); 41 | /** 42 | * Unprotected procedure 43 | **/ 44 | export const publicProcedure = t.procedure; 45 | 46 | export const router = t.router; 47 | -------------------------------------------------------------------------------- /src/utils/schemas.ts: -------------------------------------------------------------------------------- 1 | import { zfd } from 'zod-form-data'; 2 | 3 | export const uploadFileSchema = zfd.formData({ 4 | name: zfd.text(), 5 | image: zfd.file(), 6 | }); 7 | -------------------------------------------------------------------------------- /src/utils/trpc.ts: -------------------------------------------------------------------------------- 1 | import { 2 | httpBatchLink, 3 | httpLink, 4 | isNonJsonSerializable, 5 | loggerLink, 6 | splitLink, 7 | } from '@trpc/client'; 8 | import { createTRPCNext } from '@trpc/next'; 9 | import type { inferRouterInputs, inferRouterOutputs } from '@trpc/server'; 10 | import type { AppRouter } from '../pages/api/trpc/[trpc]'; 11 | 12 | function getBaseUrl() { 13 | if (typeof window !== 'undefined') { 14 | // In the browser, we return a relative URL 15 | return ''; 16 | } 17 | // When rendering on the server, we return an absolute URL 18 | 19 | // reference for vercel.com 20 | if (process.env.VERCEL_URL) { 21 | return `https://${process.env.VERCEL_URL}`; 22 | } 23 | 24 | // assume localhost 25 | return `http://localhost:${process.env.PORT ?? 3000}`; 26 | } 27 | 28 | export const trpc = createTRPCNext({ 29 | overrides: { 30 | useMutation: { 31 | /** 32 | * This function is called whenever a `.useMutation` succeeds 33 | **/ 34 | async onSuccess(opts) { 35 | /** 36 | * @note that order here matters: 37 | * The order here allows route changes in `onSuccess` without 38 | * having a flash of content change whilst redirecting. 39 | **/ 40 | 41 | // Calls the `onSuccess` defined in the `useQuery()`-options: 42 | await opts.originalFn(); 43 | 44 | // Invalidate all queries in the react-query cache: 45 | await opts.queryClient.invalidateQueries(); 46 | }, 47 | }, 48 | }, 49 | config() { 50 | const url = getBaseUrl() + '/api/trpc'; 51 | return { 52 | links: [ 53 | loggerLink({ 54 | enabled: (op) => 55 | process.env.NODE_ENV === 'development' || 56 | (op.direction === 'down' && op.result instanceof Error), 57 | }), 58 | splitLink({ 59 | condition: (op) => isNonJsonSerializable(op.input), 60 | true: httpLink({ 61 | url, 62 | }), 63 | false: httpBatchLink({ 64 | url, 65 | }), 66 | }), 67 | ], 68 | }; 69 | }, 70 | ssr: false, 71 | }); 72 | 73 | export type RouterInput = inferRouterInputs; 74 | export type RouterOutput = inferRouterOutputs; 75 | -------------------------------------------------------------------------------- /src/utils/writeFileToDisk.ts: -------------------------------------------------------------------------------- 1 | import fs from 'node:fs'; 2 | import path from 'node:path'; 3 | import { Readable } from 'node:stream'; 4 | 5 | export async function writeFileToDisk(file: File) { 6 | const rootDir = __dirname + '/../../../../..'; 7 | 8 | const nonce = Date.now(); 9 | const fileDir = path.resolve(`${rootDir}/public/uploads/${nonce}`); 10 | 11 | if (!fs.existsSync(fileDir)) { 12 | fs.mkdirSync(fileDir, { recursive: true }); 13 | } 14 | console.log('Writing', file.name, 'to', fileDir); 15 | const fd = fs.createWriteStream(path.resolve(`${fileDir}/${file.name}`)); 16 | 17 | const fileStream = Readable.fromWeb( 18 | // @ts-expect-error - unsure why this is not working 19 | file.stream(), 20 | ); 21 | for await (const chunk of fileStream) { 22 | fd.write(chunk); 23 | } 24 | fd.end(); 25 | 26 | return { 27 | url: `/uploads/${nonce}/${file.name}`, 28 | name: file.name, 29 | }; 30 | } 31 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Base Options: */ 4 | "skipLibCheck": true, 5 | "target": "es2022", 6 | "allowJs": true, 7 | "moduleDetection": "force", 8 | "isolatedModules": true, 9 | 10 | /* Strictness */ 11 | "strict": true, 12 | "checkJs": true, 13 | "allowImportingTsExtensions": true, 14 | 15 | /* Bundled projects */ 16 | "lib": ["dom", "dom.iterable", "ES2022"], 17 | "noEmit": true, 18 | "module": "Preserve", 19 | "moduleResolution": "bundler", 20 | "jsx": "preserve", 21 | "plugins": [{ "name": "next" }], 22 | "incremental": true, 23 | 24 | /* Path aliases */ 25 | "paths": { 26 | "~/*": ["./src/*"] 27 | } 28 | }, 29 | "include": [ 30 | "next-env.d.ts", 31 | "**/*.ts", 32 | "**/*.tsx", 33 | "*.js", 34 | ".next/types/**/*.ts" 35 | ], 36 | "exclude": ["node_modules"] 37 | } 38 | --------------------------------------------------------------------------------