From 54822b6c690d71bb0f8cad9979f28415cf8a95f0 Mon Sep 17 00:00:00 2001 From: Oliver Marshall Date: Fri, 30 Jan 2026 22:24:11 +0000 Subject: [PATCH 1/5] refactor: remove Redis dependency Redis was only used for a health check ping at startup. Removed: - ioredis and @socket.io/redis-streams-adapter packages - sources/storage/redis.ts - redis.ping() call from main.ts Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude Co-Authored-By: Happy --- package.json | 2 -- sources/main.ts | 2 -- sources/storage/redis.ts | 3 -- yarn.lock | 72 +--------------------------------------- 4 files changed, 1 insertion(+), 78 deletions(-) delete mode 100644 sources/storage/redis.ts diff --git a/package.json b/package.json index a2a4ffc5..6a6615b2 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,6 @@ "@fastify/bearer-auth": "^10.1.1", "@fastify/cors": "^10.0.1", "@prisma/client": "^6.11.1", - "@socket.io/redis-streams-adapter": "^0.2.2", "@types/jsonwebtoken": "^9.0.10", "@types/semver": "^7.7.0", "axios": "^1.6.8", @@ -47,7 +46,6 @@ "elevenlabs": "^1.54.0", "fastify": "^5.2.0", "fastify-type-provider-zod": "^4.0.2", - "ioredis": "^5.6.1", "jsonwebtoken": "^9.0.2", "minio": "^8.0.5", "octokit": "^5.0.3", diff --git a/sources/main.ts b/sources/main.ts index 31315a78..1cd74067 100644 --- a/sources/main.ts +++ b/sources/main.ts @@ -3,7 +3,6 @@ import { log } from "@/utils/log"; import { awaitShutdown, onShutdown } from "@/utils/shutdown"; import { db } from './storage/db'; import { startTimeout } from "./app/presence/timeout"; -import { redis } from "./storage/redis"; import { startMetricsServer } from "@/app/monitoring/metrics"; import { activityCache } from "@/app/presence/sessionCache"; import { auth } from "./app/auth/auth"; @@ -22,7 +21,6 @@ async function main() { onShutdown('activity-cache', async () => { activityCache.shutdown(); }); - await redis.ping(); // Initialize auth module await initEncrypt(); diff --git a/sources/storage/redis.ts b/sources/storage/redis.ts deleted file mode 100644 index 891bc4a5..00000000 --- a/sources/storage/redis.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { Redis } from 'ioredis'; - -export const redis = new Redis(process.env.REDIS_URL!); \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index c9500db5..8335c8a5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -461,11 +461,6 @@ resolved "https://registry.yarnpkg.com/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.3.tgz#d20c89bd41b1dd3d76d8575714aaaa3c43204b6a" integrity sha512-OWwz05d++TxzLEv4VnsTz5CmZ6mI6S05sfQGEMrNrQcOEERbX46332IvE7pO/EUiw7jUrrS40z/M7kPyjfl04g== -"@ioredis/commands@^1.1.1": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@ioredis/commands/-/commands-1.2.0.tgz#6d61b3097470af1fdbbe622795b8921d42018e11" - integrity sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg== - "@jridgewell/resolve-uri@^3.0.3": version "3.1.2" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" @@ -489,11 +484,6 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@msgpack/msgpack@~2.8.0": - version "2.8.0" - resolved "https://registry.yarnpkg.com/@msgpack/msgpack/-/msgpack-2.8.0.tgz#4210deb771ee3912964f14a15ddfb5ff877e70b9" - integrity sha512-h9u4u/jiIRKbq25PM+zymTyW6bhTzELvOoUd+AvYriWOAKpLGnIamaET3pnHYoI5iYphAHBI4ayx0MehR+VVPQ== - "@noble/curves@1.5.0": version "1.5.0" resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.5.0.tgz#7a9b9b507065d516e6dce275a1e31db8d2a100dd" @@ -1034,14 +1024,6 @@ resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz#821f8442f4175d8f0467b9daf26e3a18e2d02af2" integrity sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA== -"@socket.io/redis-streams-adapter@^0.2.2": - version "0.2.2" - resolved "https://registry.yarnpkg.com/@socket.io/redis-streams-adapter/-/redis-streams-adapter-0.2.2.tgz#149a46c546be0bd080b7a9dedb993ec75f0c1827" - integrity sha512-BMPa6oGC0wFgpMXoGksbJ75zMBwk+79pxjHc2YusdoK+X0BxN4fTsqEBuFV7yeXi9ekbi87rwlsT61+WZGVW9g== - dependencies: - "@msgpack/msgpack" "~2.8.0" - debug "~4.3.1" - "@stablelib/base64@^2.0.1": version "2.0.1" resolved "https://registry.yarnpkg.com/@stablelib/base64/-/base64-2.0.1.tgz#f1546ab26896b3490d1ab531373c0dc39e12cee1" @@ -1514,11 +1496,6 @@ check-error@^2.1.1: resolved "https://registry.yarnpkg.com/check-error/-/check-error-2.1.1.tgz#87eb876ae71ee388fa0471fe423f494be1d96ccc" integrity sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw== -cluster-key-slot@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz#88ddaa46906e303b5de30d3153b7d9fe0a0c19ac" - integrity sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA== - color-convert@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" @@ -1615,7 +1592,7 @@ dateformat@^4.6.3: resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-4.6.3.tgz#556fa6497e5217fedb78821424f8a1c22fa3f4b5" integrity sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA== -debug@^4.1.1, debug@^4.3.4: +debug@^4.1.1: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -1660,11 +1637,6 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -denque@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/denque/-/denque-2.1.0.tgz#e93e1a6569fb5e66f16a3c2a2964617d349d6ab1" - integrity sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw== - dequal@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" @@ -2147,21 +2119,6 @@ inherits@^2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -ioredis@^5.6.1: - version "5.6.1" - resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-5.6.1.tgz#1ed7dc9131081e77342503425afceaf7357ae599" - integrity sha512-UxC0Yv1Y4WRJiGQxQkP0hfdL0/5/6YvdfOOClRgJ0qppSarkhneSa6UvkMkms0AkdGimSH3Ikqm+6mkMmX7vGA== - dependencies: - "@ioredis/commands" "^1.1.1" - cluster-key-slot "^1.1.0" - debug "^4.3.4" - denque "^2.1.0" - lodash.defaults "^4.2.0" - lodash.isarguments "^3.1.0" - redis-errors "^1.2.0" - redis-parser "^3.0.0" - standard-as-callback "^2.1.0" - ipaddr.js@^2.0.1, ipaddr.js@^2.1.0: version "2.2.0" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.2.0.tgz#d33fa7bac284f4de7af949638c9d68157c6b92e8" @@ -2291,21 +2248,11 @@ light-my-request@^6.0.0: process-warning "^4.0.0" set-cookie-parser "^2.6.0" -lodash.defaults@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" - integrity sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ== - lodash.includes@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" integrity sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w== -lodash.isarguments@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" - integrity sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg== - lodash.isboolean@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" @@ -2719,18 +2666,6 @@ real-require@^0.2.0: resolved "https://registry.yarnpkg.com/real-require/-/real-require-0.2.0.tgz#209632dea1810be2ae063a6ac084fee7e33fba78" integrity sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg== -redis-errors@^1.0.0, redis-errors@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/redis-errors/-/redis-errors-1.2.0.tgz#eb62d2adb15e4eaf4610c04afe1529384250abad" - integrity sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w== - -redis-parser@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-3.0.0.tgz#b66d828cdcafe6b4b8a428a7def4c6bcac31c8b4" - integrity sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A== - dependencies: - redis-errors "^1.0.0" - reflect-metadata@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.2.2.tgz#400c845b6cba87a21f2c65c4aeb158f4fa4d9c5b" @@ -3017,11 +2952,6 @@ stackback@0.0.2: resolved "https://registry.yarnpkg.com/stackback/-/stackback-0.0.2.tgz#1ac8a0d9483848d1695e418b6d031a3c3ce68e3b" integrity sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw== -standard-as-callback@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/standard-as-callback/-/standard-as-callback-2.1.0.tgz#8953fc05359868a77b5b9739a665c5977bb7df45" - integrity sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A== - std-env@^3.9.0: version "3.9.0" resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.9.0.tgz#1a6f7243b339dca4c9fd55e1c7504c77ef23e8f1" From 124c371d8dbaf3d4fe72db268e16a6f539e114c2 Mon Sep 17 00:00:00 2001 From: Oliver Marshall Date: Fri, 30 Jan 2026 22:42:10 +0000 Subject: [PATCH 2/5] refactor: remove Minio/S3 dependency Use GitHub avatar URLs directly instead of re-hosting images. Removed: - minio and sharp packages - uploadImage.ts, processImage.ts, thumbhash.ts - S3 client initialization and loadFiles() startup check Avatar images now link directly to GitHub's CDN, which is simpler and always up-to-date. Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude Co-Authored-By: Happy --- package.json | 2 - sources/app/api/routes/accountRoutes.ts | 2 +- sources/app/events/eventRouter.ts | 2 +- sources/app/github/githubConnect.ts | 16 +- sources/app/social/type.ts | 11 +- sources/main.ts | 2 - sources/storage/files.ts | 58 ++- sources/storage/processImage.spec.ts | 10 - sources/storage/processImage.ts | 37 -- sources/storage/thumbhash.ts | 90 ---- sources/storage/uploadImage.ts | 49 --- yarn.lock | 527 +----------------------- 12 files changed, 54 insertions(+), 752 deletions(-) delete mode 100644 sources/storage/processImage.spec.ts delete mode 100644 sources/storage/processImage.ts delete mode 100644 sources/storage/thumbhash.ts delete mode 100644 sources/storage/uploadImage.ts diff --git a/package.json b/package.json index 6a6615b2..568ddd61 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,6 @@ "fastify": "^5.2.0", "fastify-type-provider-zod": "^4.0.2", "jsonwebtoken": "^9.0.2", - "minio": "^8.0.5", "octokit": "^5.0.3", "pino-pretty": "^13.0.0", "prisma": "^6.11.1", @@ -55,7 +54,6 @@ "privacy-kit": "^0.0.23", "prom-client": "^15.1.3", "semver": "^7.7.2", - "sharp": "^0.34.3", "socket.io": "^4.8.1", "socket.io-adapter": "^2.5.5", "tmp": "^0.2.3", diff --git a/sources/app/api/routes/accountRoutes.ts b/sources/app/api/routes/accountRoutes.ts index 334e8e0a..93faffea 100644 --- a/sources/app/api/routes/accountRoutes.ts +++ b/sources/app/api/routes/accountRoutes.ts @@ -30,7 +30,7 @@ export function accountRoutes(app: Fastify) { firstName: user.firstName, lastName: user.lastName, username: user.username, - avatar: user.avatar ? { ...user.avatar, url: getPublicUrl(user.avatar.path) } : null, + avatar: user.avatar ? { ...user.avatar, url: getPublicUrl(user.avatar) } : null, github: user.githubUser ? user.githubUser.profile : null, connectedServices: Array.from(connectedVendors) }); diff --git a/sources/app/events/eventRouter.ts b/sources/app/events/eventRouter.ts index 6ba61fe8..9b92127e 100644 --- a/sources/app/events/eventRouter.ts +++ b/sources/app/events/eventRouter.ts @@ -427,7 +427,7 @@ export function buildUpdateAccountUpdate(userId: string, profile: Partial { - it('should resize image', async () => { - let img = fs.readFileSync(__dirname + '/__testdata__/image.jpg'); - let result = await processImage(img); - }); -}); \ No newline at end of file diff --git a/sources/storage/processImage.ts b/sources/storage/processImage.ts deleted file mode 100644 index 2d40accb..00000000 --- a/sources/storage/processImage.ts +++ /dev/null @@ -1,37 +0,0 @@ -import sharp from "sharp"; -import { thumbhash } from "./thumbhash"; - -export async function processImage(src: Buffer) { - - // Read image - let meta = await sharp(src).metadata(); - let width = meta.width!; - let height = meta.height!; - if (meta.format !== 'png' && meta.format !== 'jpeg') { - throw new Error('Unsupported image format'); - } - - // Resize - let targetWidth = 100; - let targetHeight = 100; - if (width > height) { - targetHeight = Math.round(height * targetWidth / width); - } else if (height > width) { - targetWidth = Math.round(width * targetHeight / height); - } - - // Resize image - const { data, info } = await sharp(src).resize(targetWidth, targetHeight).ensureAlpha().raw().toBuffer({ resolveWithObject: true }); - - // Thumbhash - const binaryThumbHash = thumbhash(info.width, info.height, data); - const thumbhashStr = Buffer.from(binaryThumbHash).toString('base64'); - - return { - pixels: data, - width: width, - height: height, - thumbhash: thumbhashStr, - format: meta.format - }; -} \ No newline at end of file diff --git a/sources/storage/thumbhash.ts b/sources/storage/thumbhash.ts deleted file mode 100644 index 4257c8d8..00000000 --- a/sources/storage/thumbhash.ts +++ /dev/null @@ -1,90 +0,0 @@ -export function thumbhash(w: number, h: number, rgba: Buffer) { - // Encoding an image larger than 100x100 is slow with no benefit - if (w > 100 || h > 100) throw new Error(`${w}x${h} doesn't fit in 100x100`) - let { PI, round, max, cos, abs } = Math - - // Determine the average color - let avg_r = 0, avg_g = 0, avg_b = 0, avg_a = 0 - for (let i = 0, j = 0; i < w * h; i++, j += 4) { - let alpha = rgba[j + 3] / 255 - avg_r += alpha / 255 * rgba[j] - avg_g += alpha / 255 * rgba[j + 1] - avg_b += alpha / 255 * rgba[j + 2] - avg_a += alpha - } - if (avg_a) { - avg_r /= avg_a - avg_g /= avg_a - avg_b /= avg_a - } - - let hasAlpha = avg_a < w * h - let l_limit = hasAlpha ? 5 : 7 // Use fewer luminance bits if there's alpha - let lx = max(1, round(l_limit * w / max(w, h))) - let ly = max(1, round(l_limit * h / max(w, h))) - let l = [] // luminance - let p = [] // yellow - blue - let q = [] // red - green - let a = [] // alpha - - // Convert the image from RGBA to LPQA (composite atop the average color) - for (let i = 0, j = 0; i < w * h; i++, j += 4) { - let alpha = rgba[j + 3] / 255 - let r = avg_r * (1 - alpha) + alpha / 255 * rgba[j] - let g = avg_g * (1 - alpha) + alpha / 255 * rgba[j + 1] - let b = avg_b * (1 - alpha) + alpha / 255 * rgba[j + 2] - l[i] = (r + g + b) / 3 - p[i] = (r + g) / 2 - b - q[i] = r - g - a[i] = alpha - } - - // Encode using the DCT into DC (constant) and normalized AC (varying) terms - let encodeChannel = (channel: number[], nx: number, ny: number) => { - let dc = 0, ac = [], scale = 0, fx = [] - for (let cy = 0; cy < ny; cy++) { - for (let cx = 0; cx * ny < nx * (ny - cy); cx++) { - let f = 0 - for (let x = 0; x < w; x++) - fx[x] = cos(PI / w * cx * (x + 0.5)) - for (let y = 0; y < h; y++) - for (let x = 0, fy = cos(PI / h * cy * (y + 0.5)); x < w; x++) - f += channel[x + y * w] * fx[x] * fy - f /= w * h - if (cx || cy) { - ac.push(f) - scale = max(scale, abs(f)) - } else { - dc = f - } - } - } - if (scale) - for (let i = 0; i < ac.length; i++) - ac[i] = 0.5 + 0.5 / scale * ac[i] - return [dc, ac, scale] as const; - } - let [l_dc, l_ac, l_scale] = encodeChannel(l, max(3, lx), max(3, ly)) - let [p_dc, p_ac, p_scale] = encodeChannel(p, 3, 3) - let [q_dc, q_ac, q_scale] = encodeChannel(q, 3, 3) - let [a_dc, a_ac, a_scale] = hasAlpha ? encodeChannel(a, 5, 5) : [0, [0], 0] - - // Write the constants - let isLandscape = w > h - let header24 = round(63 * l_dc) | (round(31.5 + 31.5 * p_dc) << 6) | (round(31.5 + 31.5 * q_dc) << 12) | (round(31 * l_scale) << 18) | ((hasAlpha ? 1 : 0) << 23); - let header16 = (isLandscape ? ly : lx) | (round(63 * p_scale) << 3) | (round(63 * q_scale) << 9) | ((isLandscape ? 1 : 0) << 15); - let hash = [header24 & 255, (header24 >> 8) & 255, header24 >> 16, header16 & 255, header16 >> 8]; - let ac_start = hasAlpha ? 6 : 5; - let ac_index = 0; - if (hasAlpha) { - hash.push(round(15 * a_dc) | (round(15 * a_scale) << 4)); - } - - // Write the varying factors - for (let ac of hasAlpha ? [l_ac, p_ac, q_ac, a_ac] : [l_ac, p_ac, q_ac]) { - for (let f of ac) { - hash[ac_start + (ac_index >> 1)] |= round(15 * f) << ((ac_index++ & 1) << 2) - } - } - return new Uint8Array(hash) -} \ No newline at end of file diff --git a/sources/storage/uploadImage.ts b/sources/storage/uploadImage.ts deleted file mode 100644 index 3bcaffd4..00000000 --- a/sources/storage/uploadImage.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { randomKey } from "@/utils/randomKey"; -import { processImage } from "./processImage"; -import { s3bucket, s3client, s3host } from "./files"; -import { db } from "./db"; - -export async function uploadImage(userId: string, directory: string, prefix: string, url: string, src: Buffer) { - - // Check if image already exists - const existing = await db.uploadedFile.findFirst({ - where: { - reuseKey: 'image-url:' + url - } - }); - - if (existing && existing.thumbhash && existing.width && existing.height) { - return { - path: existing.path, - thumbhash: existing.thumbhash, - width: existing.width, - height: existing.height - }; - } - - // Process image - const processed = await processImage(src); - const key = randomKey(prefix); - let filename = `${key}.${processed.format === 'png' ? 'png' : 'jpg'}`; - await s3client.putObject(s3bucket, 'public/users/' + userId + '/' + directory + '/' + filename, src); - await db.uploadedFile.create({ - data: { - accountId: userId, - path: `public/users/${userId}/${directory}/${filename}`, - reuseKey: 'image-url:' + url, - width: processed.width, - height: processed.height, - thumbhash: processed.thumbhash - } - }); - return { - path: `public/users/${userId}/${directory}/${filename}`, - thumbhash: processed.thumbhash, - width: processed.width, - height: processed.height - } -} - -export function resolveImageUrl(path: string) { - return `https://${s3host}/${s3bucket}/${path}`; -} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 8335c8a5..90b3252d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -22,13 +22,6 @@ resolved "https://registry.yarnpkg.com/@date-fns/tz/-/tz-1.2.0.tgz#81cb3211693830babaf3b96aff51607e143030a6" integrity sha512-LBrd7MiJZ9McsOgxqWX7AaxrDjcFVjWH/tIKJd7pnR7McaslGYOP1QmmiBXdJH/H/yLCT+rcQ7FaPBUxRGUtrg== -"@emnapi/runtime@^1.4.4": - version "1.4.5" - resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.4.5.tgz#c67710d0661070f38418b6474584f159de38aba9" - integrity sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg== - dependencies: - tslib "^2.4.0" - "@esbuild/aix-ppc64@0.23.1": version "0.23.1" resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz#51299374de171dbd80bb7d838e1cfce9af36f353" @@ -331,136 +324,6 @@ "@fastify/forwarded" "^3.0.0" ipaddr.js "^2.1.0" -"@img/sharp-darwin-arm64@0.34.3": - version "0.34.3" - resolved "https://registry.yarnpkg.com/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.3.tgz#4850c8ace3c1dc13607fa07d43377b1f9aa774da" - integrity sha512-ryFMfvxxpQRsgZJqBd4wsttYQbCxsJksrv9Lw/v798JcQ8+w84mBWuXwl+TT0WJ/WrYOLaYpwQXi3sA9nTIaIg== - optionalDependencies: - "@img/sharp-libvips-darwin-arm64" "1.2.0" - -"@img/sharp-darwin-x64@0.34.3": - version "0.34.3" - resolved "https://registry.yarnpkg.com/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.3.tgz#edf93fb01479604f14ad6a64a716e2ef2bb23100" - integrity sha512-yHpJYynROAj12TA6qil58hmPmAwxKKC7reUqtGLzsOHfP7/rniNGTL8tjWX6L3CTV4+5P4ypcS7Pp+7OB+8ihA== - optionalDependencies: - "@img/sharp-libvips-darwin-x64" "1.2.0" - -"@img/sharp-libvips-darwin-arm64@1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.0.tgz#e20e9041031acde1de19da121dc5162c7d2cf251" - integrity sha512-sBZmpwmxqwlqG9ueWFXtockhsxefaV6O84BMOrhtg/YqbTaRdqDE7hxraVE3y6gVM4eExmfzW4a8el9ArLeEiQ== - -"@img/sharp-libvips-darwin-x64@1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.0.tgz#918ca81c5446f31114834cb908425a7532393185" - integrity sha512-M64XVuL94OgiNHa5/m2YvEQI5q2cl9d/wk0qFTDVXcYzi43lxuiFTftMR1tOnFQovVXNZJ5TURSDK2pNe9Yzqg== - -"@img/sharp-libvips-linux-arm64@1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.0.tgz#1a5beafc857b43f378c3030427aa981ee3edbc54" - integrity sha512-RXwd0CgG+uPRX5YYrkzKyalt2OJYRiJQ8ED/fi1tq9WQW2jsQIn0tqrlR5l5dr/rjqq6AHAxURhj2DVjyQWSOA== - -"@img/sharp-libvips-linux-arm@1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.0.tgz#bff51182d5238ca35c5fe9e9f594a18ad6a5480d" - integrity sha512-mWd2uWvDtL/nvIzThLq3fr2nnGfyr/XMXlq8ZJ9WMR6PXijHlC3ksp0IpuhK6bougvQrchUAfzRLnbsen0Cqvw== - -"@img/sharp-libvips-linux-ppc64@1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.0.tgz#10c53ccf6f2d47d71fb3fa282697072c8fe9e40e" - integrity sha512-Xod/7KaDDHkYu2phxxfeEPXfVXFKx70EAFZ0qyUdOjCcxbjqyJOEUpDe6RIyaunGxT34Anf9ue/wuWOqBW2WcQ== - -"@img/sharp-libvips-linux-s390x@1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.0.tgz#392fd7557ddc5c901f1bed7ab3c567c08833ef3b" - integrity sha512-eMKfzDxLGT8mnmPJTNMcjfO33fLiTDsrMlUVcp6b96ETbnJmd4uvZxVJSKPQfS+odwfVaGifhsB07J1LynFehw== - -"@img/sharp-libvips-linux-x64@1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.0.tgz#9315cf90a2fdcdc0e29ea7663cbd8b0f15254400" - integrity sha512-ZW3FPWIc7K1sH9E3nxIGB3y3dZkpJlMnkk7z5tu1nSkBoCgw2nSRTFHI5pB/3CQaJM0pdzMF3paf9ckKMSE9Tg== - -"@img/sharp-libvips-linuxmusl-arm64@1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.0.tgz#705e03e67d477f6f842f37eb7f66285b1150dc06" - integrity sha512-UG+LqQJbf5VJ8NWJ5Z3tdIe/HXjuIdo4JeVNADXBFuG7z9zjoegpzzGIyV5zQKi4zaJjnAd2+g2nna8TZvuW9Q== - -"@img/sharp-libvips-linuxmusl-x64@1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.0.tgz#ec905071cc538df64848d5900e0d386d77c55f13" - integrity sha512-SRYOLR7CXPgNze8akZwjoGBoN1ThNZoqpOgfnOxmWsklTGVfJiGJoC/Lod7aNMGA1jSsKWM1+HRX43OP6p9+6Q== - -"@img/sharp-linux-arm64@0.34.3": - version "0.34.3" - resolved "https://registry.yarnpkg.com/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.3.tgz#476f8f13ce192555391ae9d4bc658637a6acf3e5" - integrity sha512-QdrKe3EvQrqwkDrtuTIjI0bu6YEJHTgEeqdzI3uWJOH6G1O8Nl1iEeVYRGdj1h5I21CqxSvQp1Yv7xeU3ZewbA== - optionalDependencies: - "@img/sharp-libvips-linux-arm64" "1.2.0" - -"@img/sharp-linux-arm@0.34.3": - version "0.34.3" - resolved "https://registry.yarnpkg.com/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.3.tgz#9898cd68ea3e3806b94fe25736d5d7ecb5eac121" - integrity sha512-oBK9l+h6KBN0i3dC8rYntLiVfW8D8wH+NPNT3O/WBHeW0OQWCjfWksLUaPidsrDKpJgXp3G3/hkmhptAW0I3+A== - optionalDependencies: - "@img/sharp-libvips-linux-arm" "1.2.0" - -"@img/sharp-linux-ppc64@0.34.3": - version "0.34.3" - resolved "https://registry.yarnpkg.com/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.3.tgz#6a7cd4c608011333a0ddde6d96e03ac042dd9079" - integrity sha512-GLtbLQMCNC5nxuImPR2+RgrviwKwVql28FWZIW1zWruy6zLgA5/x2ZXk3mxj58X/tszVF69KK0Is83V8YgWhLA== - optionalDependencies: - "@img/sharp-libvips-linux-ppc64" "1.2.0" - -"@img/sharp-linux-s390x@0.34.3": - version "0.34.3" - resolved "https://registry.yarnpkg.com/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.3.tgz#48e27ab969efe97d270e39297654c0e0c9b42919" - integrity sha512-3gahT+A6c4cdc2edhsLHmIOXMb17ltffJlxR0aC2VPZfwKoTGZec6u5GrFgdR7ciJSsHT27BD3TIuGcuRT0KmQ== - optionalDependencies: - "@img/sharp-libvips-linux-s390x" "1.2.0" - -"@img/sharp-linux-x64@0.34.3": - version "0.34.3" - resolved "https://registry.yarnpkg.com/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.3.tgz#5aa77ad4aa447ddf6d642e2a2c5599eb1292dfaa" - integrity sha512-8kYso8d806ypnSq3/Ly0QEw90V5ZoHh10yH0HnrzOCr6DKAPI6QVHvwleqMkVQ0m+fc7EH8ah0BB0QPuWY6zJQ== - optionalDependencies: - "@img/sharp-libvips-linux-x64" "1.2.0" - -"@img/sharp-linuxmusl-arm64@0.34.3": - version "0.34.3" - resolved "https://registry.yarnpkg.com/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.3.tgz#62053a9d77c7d4632c677619325b741254689dd7" - integrity sha512-vAjbHDlr4izEiXM1OTggpCcPg9tn4YriK5vAjowJsHwdBIdx0fYRsURkxLG2RLm9gyBq66gwtWI8Gx0/ov+JKQ== - optionalDependencies: - "@img/sharp-libvips-linuxmusl-arm64" "1.2.0" - -"@img/sharp-linuxmusl-x64@0.34.3": - version "0.34.3" - resolved "https://registry.yarnpkg.com/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.3.tgz#5107c7709c7e0a44fe5abef59829f1de86fa0a3a" - integrity sha512-gCWUn9547K5bwvOn9l5XGAEjVTTRji4aPTqLzGXHvIr6bIDZKNTA34seMPgM0WmSf+RYBH411VavCejp3PkOeQ== - optionalDependencies: - "@img/sharp-libvips-linuxmusl-x64" "1.2.0" - -"@img/sharp-wasm32@0.34.3": - version "0.34.3" - resolved "https://registry.yarnpkg.com/@img/sharp-wasm32/-/sharp-wasm32-0.34.3.tgz#c1dcabb834ec2f71308a810b399bb6e6e3b79619" - integrity sha512-+CyRcpagHMGteySaWos8IbnXcHgfDn7pO2fiC2slJxvNq9gDipYBN42/RagzctVRKgxATmfqOSulgZv5e1RdMg== - dependencies: - "@emnapi/runtime" "^1.4.4" - -"@img/sharp-win32-arm64@0.34.3": - version "0.34.3" - resolved "https://registry.yarnpkg.com/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.3.tgz#3e8654e368bb349d45799a0d7aeb29db2298628e" - integrity sha512-MjnHPnbqMXNC2UgeLJtX4XqoVHHlZNd+nPt1kRPmj63wURegwBhZlApELdtxM2OIZDRv/DFtLcNhVbd1z8GYXQ== - -"@img/sharp-win32-ia32@0.34.3": - version "0.34.3" - resolved "https://registry.yarnpkg.com/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.3.tgz#9d4c105e8d5074a351a81a0b6d056e0af913bf76" - integrity sha512-xuCdhH44WxuXgOM714hn4amodJMZl3OEvf0GVTm0BEyMeA2to+8HEdRPShH0SLYptJY1uBw+SCFP9WVQi1Q/cw== - -"@img/sharp-win32-x64@0.34.3": - version "0.34.3" - resolved "https://registry.yarnpkg.com/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.3.tgz#d20c89bd41b1dd3d76d8575714aaaa3c43204b6a" - integrity sha512-OWwz05d++TxzLEv4VnsTz5CmZ6mI6S05sfQGEMrNrQcOEERbX46332IvE7pO/EUiw7jUrrS40z/M7kPyjfl04g== - "@jridgewell/resolve-uri@^3.0.3": version "3.1.2" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" @@ -1264,11 +1127,6 @@ loupe "^3.1.3" tinyrainbow "^2.0.0" -"@zxing/text-encoding@0.9.0": - version "0.9.0" - resolved "https://registry.yarnpkg.com/@zxing/text-encoding/-/text-encoding-0.9.0.tgz#fb50ffabc6c7c66a0c96b4c03e3d9be74864b70b" - integrity sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA== - abort-controller@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" @@ -1342,11 +1200,6 @@ assertion-error@^2.0.1: resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-2.0.1.tgz#f641a196b335690b1070bf00b6e7593fec190bf7" integrity sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA== -async@^3.2.4: - version "3.2.6" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.6.tgz#1b0728e14929d51b85b449b7f06e27c1145e38ce" - integrity sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA== - asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -1357,13 +1210,6 @@ atomic-sleep@^1.0.0: resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b" integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ== -available-typed-arrays@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846" - integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ== - dependencies: - possible-typed-array-names "^1.0.0" - avvio@^9.0.0: version "9.1.0" resolved "https://registry.yarnpkg.com/avvio/-/avvio-9.1.0.tgz#0ff80ed211682441d8aa39ff21a4b9d022109c44" @@ -1401,28 +1247,11 @@ bintrees@1.0.2: resolved "https://registry.yarnpkg.com/bintrees/-/bintrees-1.0.2.tgz#49f896d6e858a4a499df85c38fb399b9aff840f8" integrity sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw== -block-stream2@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/block-stream2/-/block-stream2-2.1.0.tgz#ac0c5ef4298b3857796e05be8ebed72196fa054b" - integrity sha512-suhjmLI57Ewpmq00qaygS8UgEq2ly2PCItenIyhMqVjo4t4pGzqMvfgJuX8iWTeSDdfSSqS6j38fL4ToNL7Pfg== - dependencies: - readable-stream "^3.4.0" - bottleneck@^2.15.3: version "2.19.5" resolved "https://registry.yarnpkg.com/bottleneck/-/bottleneck-2.19.5.tgz#5df0b90f59fd47656ebe63c78a98419205cadd91" integrity sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw== -browser-or-node@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/browser-or-node/-/browser-or-node-2.1.1.tgz#738790b3a86a8fc020193fa581273fbe65eaea0f" - integrity sha512-8CVjaLJGuSKMVTxJ2DpBl5XnlNDiT4cQFeuCJJrvJmts9YrTZDizTX7PjC2s6W4x+MBGZeEY6dGMrF04/6Hgqg== - -buffer-crc32@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-1.0.0.tgz#a10993b9055081d55304bd9feb4a072de179f405" - integrity sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w== - buffer-equal-constant-time@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" @@ -1441,7 +1270,7 @@ cac@^6.7.14: resolved "https://registry.yarnpkg.com/cac/-/cac-6.7.14.tgz#804e1e6f506ee363cb0e3ccbb09cad5dd9870959" integrity sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ== -call-bind-apply-helpers@^1.0.0, call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: +call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6" integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== @@ -1449,17 +1278,7 @@ call-bind-apply-helpers@^1.0.0, call-bind-apply-helpers@^1.0.1, call-bind-apply- es-errors "^1.3.0" function-bind "^1.1.2" -call-bind@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.8.tgz#0736a9660f537e3388826f440d5ec45f744eaa4c" - integrity sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww== - dependencies: - call-bind-apply-helpers "^1.0.0" - es-define-property "^1.0.0" - get-intrinsic "^1.2.4" - set-function-length "^1.2.2" - -call-bound@^1.0.2, call-bound@^1.0.3, call-bound@^1.0.4: +call-bound@^1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/call-bound/-/call-bound-1.0.4.tgz#238de935d2a2a692928c538c7ccfa91067fd062a" integrity sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg== @@ -1503,27 +1322,11 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@^1.0.0, color-name@~1.1.4: +color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -color-string@^1.9.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.1.tgz#4467f9146f036f855b764dfb5bf8582bf342c7a4" - integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg== - dependencies: - color-name "^1.0.0" - simple-swizzle "^0.2.2" - -color@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/color/-/color-4.2.3.tgz#d781ecb5e57224ee43ea9627560107c0e0c6463a" - integrity sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A== - dependencies: - color-convert "^2.0.1" - color-string "^1.9.0" - colorette@^2.0.7: version "2.0.20" resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" @@ -1613,25 +1416,11 @@ debug@~4.3.1, debug@~4.3.2, debug@~4.3.4: dependencies: ms "^2.1.3" -decode-uri-component@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" - integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== - deep-eql@^5.0.1: version "5.0.2" resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-5.0.2.tgz#4b756d8d770a9257300825d52a2c2cff99c3a341" integrity sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q== -define-data-property@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" - integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== - dependencies: - es-define-property "^1.0.0" - es-errors "^1.3.0" - gopd "^1.0.1" - delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -1642,11 +1431,6 @@ dequal@^2.0.3: resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== -detect-libc@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.4.tgz#f04715b8ba815e53b4d8109655b6508a6865a7e8" - integrity sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA== - diff@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" @@ -1735,7 +1519,7 @@ engine.io@~6.6.0: engine.io-parser "~5.2.1" ws "~8.17.1" -es-define-property@^1.0.0, es-define-property@^1.0.1: +es-define-property@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa" integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== @@ -1830,11 +1614,6 @@ event-target-shim@^5.0.0: resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== -eventemitter3@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" - integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== - events@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" @@ -1914,13 +1693,6 @@ fast-uri@^3.0.0, fast-uri@^3.0.1: resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.0.6.tgz#88f130b77cfaea2378d56bf970dea21257a68748" integrity sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw== -fast-xml-parser@^4.4.1: - version "4.5.3" - resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.5.3.tgz#c54d6b35aa0f23dc1ea60b6c884340c006dc6efb" - integrity sha512-RKihhV+SHsIUGXObeVy9AXiBbFwkVk7Syp8XgwN5U3JV416+Gwp/GO9i0JYKmikykgz/UHRrrV4ROuZEo/T0ig== - dependencies: - strnum "^1.1.1" - fastify-plugin@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/fastify-plugin/-/fastify-plugin-5.0.1.tgz#82d44e6fe34d1420bb5a4f7bee434d501e41939f" @@ -1967,11 +1739,6 @@ fdir@^6.4.4: resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.4.5.tgz#328e280f3a23699362f95f2e82acf978a0c0cb49" integrity sha512-4BG7puHpVsIYxZUbiUE3RqGloLaSSwzYie5jvasC4LWuBWzZawynvYouhjbQKw2JuIGYdm0DzIxl8iVidKlUEw== -filter-obj@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b" - integrity sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ== - find-my-way@^9.0.0: version "9.2.0" resolved "https://registry.yarnpkg.com/find-my-way/-/find-my-way-9.2.0.tgz#6f845aac6227adcb683134f60bd9e8c144af21da" @@ -1986,13 +1753,6 @@ follow-redirects@^1.15.6: resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== -for-each@^0.3.5: - version "0.3.5" - resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.5.tgz#d650688027826920feeb0af747ee7b9421a41d47" - integrity sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg== - dependencies: - is-callable "^1.2.7" - form-data-encoder@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-4.0.2.tgz#dd286fd5f9049e8ded1d44ce427f5e29185c7c12" @@ -2022,7 +1782,7 @@ function-bind@^1.1.2: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== -get-intrinsic@^1.2.4, get-intrinsic@^1.2.5, get-intrinsic@^1.3.0: +get-intrinsic@^1.2.5, get-intrinsic@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01" integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== @@ -2038,7 +1798,7 @@ get-intrinsic@^1.2.4, get-intrinsic@^1.2.5, get-intrinsic@^1.3.0: hasown "^2.0.2" math-intrinsics "^1.1.0" -get-proto@^1.0.0, get-proto@^1.0.1: +get-proto@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1" integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g== @@ -2063,7 +1823,7 @@ globrex@^0.1.2: resolved "https://registry.yarnpkg.com/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098" integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg== -gopd@^1.0.1, gopd@^1.2.0: +gopd@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1" integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== @@ -2073,25 +1833,11 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-property-descriptors@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" - integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== - dependencies: - es-define-property "^1.0.0" - -has-symbols@^1.0.3, has-symbols@^1.1.0: +has-symbols@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338" integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== -has-tostringtag@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" - integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== - dependencies: - has-symbols "^1.0.3" - hasown@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" @@ -2114,66 +1860,16 @@ ieee754@^1.2.1: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== -inherits@^2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -ipaddr.js@^2.0.1, ipaddr.js@^2.1.0: +ipaddr.js@^2.1.0: version "2.2.0" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.2.0.tgz#d33fa7bac284f4de7af949638c9d68157c6b92e8" integrity sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA== -is-arguments@^1.0.4: - version "1.2.0" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.2.0.tgz#ad58c6aecf563b78ef2bf04df540da8f5d7d8e1b" - integrity sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA== - dependencies: - call-bound "^1.0.2" - has-tostringtag "^1.0.2" - -is-arrayish@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" - integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== - -is-callable@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" - integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== - -is-generator-function@^1.0.7: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.1.0.tgz#bf3eeda931201394f57b5dba2800f91a238309ca" - integrity sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ== - dependencies: - call-bound "^1.0.3" - get-proto "^1.0.0" - has-tostringtag "^1.0.2" - safe-regex-test "^1.1.0" - -is-regex@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.2.1.tgz#76d70a3ed10ef9be48eb577887d74205bf0cad22" - integrity sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g== - dependencies: - call-bound "^1.0.2" - gopd "^1.2.0" - has-tostringtag "^1.0.2" - hasown "^2.0.2" - is-stream@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== -is-typed-array@^1.1.3: - version "1.1.15" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.15.tgz#4bfb4a45b61cee83a5a46fba778e4e8d59c0ce0b" - integrity sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ== - dependencies: - which-typed-array "^1.1.16" - isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -2283,11 +1979,6 @@ lodash.once@^4.0.0: resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== -lodash@^4.17.21: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - loupe@^3.1.0, loupe@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/loupe/-/loupe-3.1.3.tgz#042a8f7986d77f3d0f98ef7990a2b2fef18b0fd2" @@ -2327,7 +2018,7 @@ mime-db@1.52.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@^2.1.12, mime-types@^2.1.35, mime-types@~2.1.34: +mime-types@^2.1.12, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== @@ -2344,26 +2035,6 @@ minimist@^1.2.6: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== -minio@^8.0.5: - version "8.0.5" - resolved "https://registry.yarnpkg.com/minio/-/minio-8.0.5.tgz#bfc4d07734ba956efe90bdbcf53b97f56a2c10f2" - integrity sha512-/vAze1uyrK2R/DSkVutE4cjVoAowvIQ18RAwn7HrqnLecLlMazFnY0oNBqfuoAWvu7mZIGX75AzpuV05TJeoHg== - dependencies: - async "^3.2.4" - block-stream2 "^2.1.0" - browser-or-node "^2.1.1" - buffer-crc32 "^1.0.0" - eventemitter3 "^5.0.1" - fast-xml-parser "^4.4.1" - ipaddr.js "^2.0.1" - lodash "^4.17.21" - mime-types "^2.1.35" - query-string "^7.1.3" - stream-json "^1.8.0" - through2 "^4.0.2" - web-encoding "^1.1.5" - xml2js "^0.5.0 || ^0.6.2" - mnemonist@0.40.0: version "0.40.0" resolved "https://registry.yarnpkg.com/mnemonist/-/mnemonist-0.40.0.tgz#72e866d7f1e261d0c589717ff2bcfd6feb802db2" @@ -2529,11 +2200,6 @@ pino@^9.0.0: sonic-boom "^4.0.1" thread-stream "^3.0.0" -possible-typed-array-names@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz#93e3582bc0e5426586d9d07b79ee40fc841de4ae" - integrity sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg== - postcss@^8.5.3: version "8.5.4" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.4.tgz#d61014ac00e11d5f58458ed7247d899bd65f99c0" @@ -2626,30 +2292,11 @@ qs@^6.13.1: dependencies: side-channel "^1.1.0" -query-string@^7.1.3: - version "7.1.3" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-7.1.3.tgz#a1cf90e994abb113a325804a972d98276fe02328" - integrity sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg== - dependencies: - decode-uri-component "^0.2.2" - filter-obj "^1.1.0" - split-on-first "^1.0.0" - strict-uri-encode "^2.0.0" - quick-format-unescaped@^4.0.3: version "4.0.4" resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz#93ef6dd8d3453cbc7970dd614fad4c5954d6b5a7" integrity sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg== -readable-stream@3, readable-stream@^3.4.0: - version "3.6.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - readable-stream@^4.5.2: version "4.7.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-4.7.0.tgz#cedbd8a1146c13dfff8dab14068028d58c15ac91" @@ -2730,15 +2377,6 @@ safe-buffer@^5.0.1, safe-buffer@~5.2.0: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== -safe-regex-test@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.1.0.tgz#7f87dfb67a3150782eaaf18583ff5d1711ac10c1" - integrity sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw== - dependencies: - call-bound "^1.0.2" - es-errors "^1.3.0" - is-regex "^1.2.1" - safe-regex2@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/safe-regex2/-/safe-regex2-4.0.1.tgz#b0a4b0216c1dd0256af987b7aea473e1c91543a8" @@ -2751,11 +2389,6 @@ safe-stable-stringify@^2.3.1: resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz#4ca2f8e385f2831c432a719b108a3bf7af42a1dd" integrity sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA== -sax@>=0.6.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.4.1.tgz#44cc8988377f126304d3b3fc1010c733b929ef0f" - integrity sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg== - secure-json-parse@^2.4.0: version "2.7.0" resolved "https://registry.yarnpkg.com/secure-json-parse/-/secure-json-parse-2.7.0.tgz#5a5f9cd6ae47df23dba3151edd06855d47e09862" @@ -2783,50 +2416,6 @@ set-cookie-parser@^2.6.0: resolved "https://registry.yarnpkg.com/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz#3016f150072202dfbe90fadee053573cc89d2943" integrity sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ== -set-function-length@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" - integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== - dependencies: - define-data-property "^1.1.4" - es-errors "^1.3.0" - function-bind "^1.1.2" - get-intrinsic "^1.2.4" - gopd "^1.0.1" - has-property-descriptors "^1.0.2" - -sharp@^0.34.3: - version "0.34.3" - resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.34.3.tgz#10a03bcd15fb72f16355461af0b9245ccb8a5da3" - integrity sha512-eX2IQ6nFohW4DbvHIOLRB3MHFpYqaqvXd3Tp5e/T/dSH83fxaNJQRvDMhASmkNTsNTVF2/OOopzRCt7xokgPfg== - dependencies: - color "^4.2.3" - detect-libc "^2.0.4" - semver "^7.7.2" - optionalDependencies: - "@img/sharp-darwin-arm64" "0.34.3" - "@img/sharp-darwin-x64" "0.34.3" - "@img/sharp-libvips-darwin-arm64" "1.2.0" - "@img/sharp-libvips-darwin-x64" "1.2.0" - "@img/sharp-libvips-linux-arm" "1.2.0" - "@img/sharp-libvips-linux-arm64" "1.2.0" - "@img/sharp-libvips-linux-ppc64" "1.2.0" - "@img/sharp-libvips-linux-s390x" "1.2.0" - "@img/sharp-libvips-linux-x64" "1.2.0" - "@img/sharp-libvips-linuxmusl-arm64" "1.2.0" - "@img/sharp-libvips-linuxmusl-x64" "1.2.0" - "@img/sharp-linux-arm" "0.34.3" - "@img/sharp-linux-arm64" "0.34.3" - "@img/sharp-linux-ppc64" "0.34.3" - "@img/sharp-linux-s390x" "0.34.3" - "@img/sharp-linux-x64" "0.34.3" - "@img/sharp-linuxmusl-arm64" "0.34.3" - "@img/sharp-linuxmusl-x64" "0.34.3" - "@img/sharp-wasm32" "0.34.3" - "@img/sharp-win32-arm64" "0.34.3" - "@img/sharp-win32-ia32" "0.34.3" - "@img/sharp-win32-x64" "0.34.3" - shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -2889,13 +2478,6 @@ signal-exit@^3.0.3: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== -simple-swizzle@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" - integrity sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg== - dependencies: - is-arrayish "^0.3.1" - socket.io-adapter@^2.5.5, socket.io-adapter@~2.5.2: version "2.5.5" resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz#c7a1f9c703d7756844751b6ff9abfc1780664082" @@ -2937,11 +2519,6 @@ source-map-js@^1.2.1: resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== -split-on-first@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" - integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw== - split2@^4.0.0: version "4.2.0" resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" @@ -2957,24 +2534,7 @@ std-env@^3.9.0: resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.9.0.tgz#1a6f7243b339dca4c9fd55e1c7504c77ef23e8f1" integrity sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw== -stream-chain@^2.2.5: - version "2.2.5" - resolved "https://registry.yarnpkg.com/stream-chain/-/stream-chain-2.2.5.tgz#b30967e8f14ee033c5b9a19bbe8a2cba90ba0d09" - integrity sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA== - -stream-json@^1.8.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/stream-json/-/stream-json-1.9.1.tgz#e3fec03e984a503718946c170db7d74556c2a187" - integrity sha512-uWkjJ+2Nt/LO9Z/JyKZbMusL8Dkh97uUBTv3AJQ74y07lVahLY4eEFsPsE97pxYBwr8nnjMAIch5eqI0gPShyw== - dependencies: - stream-chain "^2.2.5" - -strict-uri-encode@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" - integrity sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ== - -string_decoder@^1.1.1, string_decoder@^1.3.0: +string_decoder@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== @@ -2991,11 +2551,6 @@ strip-json-comments@^3.1.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -strnum@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.1.2.tgz#57bca4fbaa6f271081715dbc9ed7cee5493e28e4" - integrity sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA== - supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" @@ -3017,13 +2572,6 @@ thread-stream@^3.0.0: dependencies: real-require "^0.2.0" -through2@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/through2/-/through2-4.0.2.tgz#a7ce3ac2a7a8b0b966c80e7c49f0484c3b239764" - integrity sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw== - dependencies: - readable-stream "3" - tinybench@^2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/tinybench/-/tinybench-2.9.0.tgz#103c9f8ba6d7237a47ab6dd1dcff77251863426b" @@ -3101,7 +2649,7 @@ tslib@^1.9.3: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.4.0, tslib@^2.7.0, tslib@^2.8.1: +tslib@^2.7.0, tslib@^2.8.1: version "2.8.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== @@ -3158,22 +2706,6 @@ url-join@4.0.1: resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.1.tgz#b642e21a2646808ffa178c4c5fda39844e12cde7" integrity sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA== -util-deprecate@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== - -util@^0.12.3: - version "0.12.5" - resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" - integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== - dependencies: - inherits "^2.0.3" - is-arguments "^1.0.4" - is-generator-function "^1.0.7" - is-typed-array "^1.1.3" - which-typed-array "^1.1.2" - uuid@^9.0.1: version "9.0.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" @@ -3252,15 +2784,6 @@ vitest@^3.2.0: vite-node "3.2.0" why-is-node-running "^2.3.0" -web-encoding@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/web-encoding/-/web-encoding-1.1.5.tgz#fc810cf7667364a6335c939913f5051d3e0c4864" - integrity sha512-HYLeVCdJ0+lBYV2FvNZmv3HJ2Nt0QYXqZojk3d9FJOLkwnuhzM9tmamh8d7HPM8QqjKH8DeHkFTx+CFlWpZZDA== - dependencies: - util "^0.12.3" - optionalDependencies: - "@zxing/text-encoding" "0.9.0" - webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" @@ -3274,19 +2797,6 @@ whatwg-url@^5.0.0: tr46 "~0.0.3" webidl-conversions "^3.0.0" -which-typed-array@^1.1.16, which-typed-array@^1.1.2: - version "1.1.19" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.19.tgz#df03842e870b6b88e117524a4b364b6fc689f956" - integrity sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw== - dependencies: - available-typed-arrays "^1.0.7" - call-bind "^1.0.8" - call-bound "^1.0.4" - for-each "^0.3.5" - get-proto "^1.0.1" - gopd "^1.2.0" - has-tostringtag "^1.0.2" - which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" @@ -3312,19 +2822,6 @@ ws@~8.17.1: resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b" integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ== -"xml2js@^0.5.0 || ^0.6.2": - version "0.6.2" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.6.2.tgz#dd0b630083aa09c161e25a4d0901e2b2a929b499" - integrity sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA== - dependencies: - sax ">=0.6.0" - xmlbuilder "~11.0.0" - -xmlbuilder@~11.0.0: - version "11.0.1" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" - integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== - yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" From 25507f6534448f29e89e18dfaad6c23a79030221 Mon Sep 17 00:00:00 2001 From: Oliver Marshall Date: Fri, 30 Jan 2026 23:05:03 +0000 Subject: [PATCH 3/5] refactor: migrate from PostgreSQL to SQLite MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simplifies deployment to a single file database. Changes: - Prisma provider: postgresql → sqlite - Removed relationJoins preview feature (Postgres-only) - Removed ordered index syntax (SQLite limitation) - Removed Serializable isolation (SQLite is single-writer) - Removed case-insensitive search mode (SQLite limitation) - Deleted 37 PostgreSQL migrations (fresh start required) - Updated scripts: db:push/db:reset replace migrate commands - Removed Docker commands for postgres/redis/minio BREAKING: Requires fresh database. Existing deployments need to re-authenticate all clients (mobile app, CLI daemons). Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude Co-Authored-By: Happy --- .env.dev | 14 +----- .gitignore | 9 ++-- package.json | 13 ++---- .../20250713002718_initial/migration.sql | 43 ----------------- .../20250713004156_add_sessions/migration.sql | 46 ------------------- .../migration.sql | 12 ----- .../migration.sql | 8 ---- .../migration.sql | 3 -- .../migration.sql | 4 -- .../migration.sql | 11 ----- .../migration.sql | 16 ------- .../migration.sql | 13 ------ .../migration.sql | 5 -- .../migration.sql | 27 ----------- .../migration.sql | 11 ----- .../migration.sql | 2 - .../migration.sql | 2 - .../migration.sql | 23 ---------- .../migration.sql | 17 ------- .../migration.sql | 3 -- .../migration.sql | 2 - .../migration.sql | 2 - .../migration.sql | 26 ----------- .../migration.sql | 24 ---------- .../migration.sql | 2 - .../migration.sql | 4 -- .../migration.sql | 22 --------- .../migration.sql | 2 - .../migration.sql | 2 - .../migration.sql | 2 - .../migration.sql | 24 ---------- .../migration.sql | 34 -------------- .../migration.sql | 26 ----------- .../migration.sql | 16 ------- .../20250920025406_add_username/migration.sql | 11 ----- .../migration.sql | 8 ---- .../migration.sql | 27 ----------- .../migration.sql | 2 - .../20250922000310_add_user_kv/migration.sql | 21 --------- prisma/migrations/migration_lock.toml | 3 -- prisma/schema.prisma | 10 ++-- sources/app/api/routes/userRoutes.ts | 4 +- sources/storage/inTx.ts | 2 +- 43 files changed, 18 insertions(+), 540 deletions(-) delete mode 100644 prisma/migrations/20250713002718_initial/migration.sql delete mode 100644 prisma/migrations/20250713004156_add_sessions/migration.sql delete mode 100644 prisma/migrations/20250713032124_add_tag_to_session/migration.sql delete mode 100644 prisma/migrations/20250714030924_add_session_metadata/migration.sql delete mode 100644 prisma/migrations/20250714032124_session_timeouts/migration.sql delete mode 100644 prisma/migrations/20250715012822_add_metadata_version_agent_state/migration.sql delete mode 100644 prisma/migrations/20250718031550_add_local_id_to_session_message/migration.sql delete mode 100644 prisma/migrations/20250718032748_add_push_token/migration.sql delete mode 100644 prisma/migrations/20250719042829_add_terminal_auth_request/migration.sql delete mode 100644 prisma/migrations/20250719061508_add_response_account/migration.sql delete mode 100644 prisma/migrations/20250721073743_add_usage_report/migration.sql delete mode 100644 prisma/migrations/20250726092110_remove_updates/migration.sql delete mode 100644 prisma/migrations/20250726205102_add_settings_to_account/migration.sql delete mode 100644 prisma/migrations/20250726205206_add_account_settings_version/migration.sql delete mode 100644 prisma/migrations/20250812092041_add_machine_model/migration.sql delete mode 100644 prisma/migrations/20250816171155_add_app_to_app_authentication/migration.sql delete mode 100644 prisma/migrations/20250818044258_add_daemon_state_to_machine/migration.sql delete mode 100644 prisma/migrations/20250820051609_add_session_id_seq_index/migration.sql delete mode 100644 prisma/migrations/20250820052449_add_session_sort/migration.sql delete mode 100644 prisma/migrations/20250827015520_add_github_entities/migration.sql delete mode 100644 prisma/migrations/20250827044624_add_user_profile_fields/migration.sql delete mode 100644 prisma/migrations/20250827045037_add_reuse_key_to_file/migration.sql delete mode 100644 prisma/migrations/20250827051355_add_image_parameters/migration.sql delete mode 100644 prisma/migrations/20250901205028_add_service_account_tokens/migration.sql delete mode 100644 prisma/migrations/20250908050408_add_data_encryption_key/migration.sql delete mode 100644 prisma/migrations/20250908052114_add_machine_data_encryption_key/migration.sql delete mode 100644 prisma/migrations/20250911030241_add_version2_field/migration.sql delete mode 100644 prisma/migrations/20250917052000_add_artefacts/migration.sql delete mode 100644 prisma/migrations/20250917055002_add_access_key/migration.sql delete mode 100644 prisma/migrations/20250918045344_add_friendships/migration.sql delete mode 100644 prisma/migrations/20250919021354_fix_relationship_status/migration.sql delete mode 100644 prisma/migrations/20250920025406_add_username/migration.sql delete mode 100644 prisma/migrations/20250920035415_make_github_user_id_unique/migration.sql delete mode 100644 prisma/migrations/20250920213557_add_user_feed/migration.sql delete mode 100644 prisma/migrations/20250920215413_add_last_notified_at/migration.sql delete mode 100644 prisma/migrations/20250922000310_add_user_kv/migration.sql delete mode 100644 prisma/migrations/migration_lock.toml diff --git a/.env.dev b/.env.dev index b8021fc8..3ea8f7e0 100644 --- a/.env.dev +++ b/.env.dev @@ -1,4 +1,4 @@ -DATABASE_URL=postgresql://postgres:postgres@localhost:5432/handy +DATABASE_URL=file:./happy.db HANDY_MASTER_SECRET=your-super-secret-key-for-local-development PORT=3005 @@ -9,18 +9,8 @@ METRICS_PORT=9090 # Uncomment to enable centralized logging for AI debugging (creates .logs directory) DANGEROUSLY_LOG_TO_SERVER_FOR_AI_AUTO_DEBUGGING=true -# --- Local S3/MinIO --- -# Defaults for local MinIO started via `yarn s3` -S3_HOST=localhost -S3_PORT=9000 -S3_USE_SSL=false -S3_ACCESS_KEY=minioadmin -S3_SECRET_KEY=minioadmin -S3_BUCKET=happy -S3_PUBLIC_URL=http://localhost:9000/happy - # --- Voice Feature --- # 11Labs API for voice conversations (required for voice feature) -# Secret - congiured in .env, not checked in +# Secret - configured in .env, not checked in NODE_ENV=development diff --git a/.gitignore b/.gitignore index c75f9856..c2df10da 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,11 @@ node_modules .env +.env.local dist -.pgdata -.minio -.env.local -.env +# SQLite database +*.db +*.db-journal .logs/ - .claude/ diff --git a/package.json b/package.json index 568ddd61..61cc607b 100644 --- a/package.json +++ b/package.json @@ -9,17 +9,12 @@ "scripts": { "build": "tsc --noEmit", "start": "tsx ./sources/main.ts", - "dev": "lsof -ti tcp:3005 | xargs kill -9 && tsx --env-file=.env --env-file=.env.dev ./sources/main.ts", + "dev": "lsof -ti tcp:3005 | xargs kill -9 2>/dev/null; tsx --env-file=.env --env-file=.env.dev ./sources/main.ts", "test": "vitest run", - "migrate": "dotenv -e .env.dev -- prisma migrate dev", - "migrate:reset": "dotenv -e .env.dev -- prisma migrate reset", + "db:push": "dotenv -e .env.dev -- prisma db push", + "db:reset": "rm -f happy.db && dotenv -e .env.dev -- prisma db push", "generate": "prisma generate", - "postinstall": "prisma generate", - "db": "docker run -d -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=handy -v $(pwd)/.pgdata:/var/lib/postgresql/data -p 5432:5432 postgres", - "redis": "docker run -d -p 6379:6379 redis", - "s3": "docker run -d --name minio -p 9000:9000 -p 9001:9001 -e MINIO_ROOT_USER=minioadmin -e MINIO_ROOT_PASSWORD=minioadmin -v $(pwd)/.minio/data:/data minio/minio server /data --console-address :9001", - "s3:down": "docker rm -f minio || true", - "s3:init": "dotenv -e .env.dev -- docker run --rm --network container:minio --entrypoint /bin/sh minio/mc -c \"mc alias set local http://localhost:9000 $S3_ACCESS_KEY $S3_SECRET_KEY && mc mb -p local/$S3_BUCKET || true && mc anonymous set download local/$S3_BUCKET\"" + "postinstall": "prisma generate" }, "devDependencies": { "@types/chalk": "^2.2.0", diff --git a/prisma/migrations/20250713002718_initial/migration.sql b/prisma/migrations/20250713002718_initial/migration.sql deleted file mode 100644 index 73c4e773..00000000 --- a/prisma/migrations/20250713002718_initial/migration.sql +++ /dev/null @@ -1,43 +0,0 @@ --- CreateTable -CREATE TABLE "Account" ( - "id" TEXT NOT NULL, - "publicKey" TEXT NOT NULL, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL, - - CONSTRAINT "Account_pkey" PRIMARY KEY ("id") -); - --- CreateTable -CREATE TABLE "GlobalLock" ( - "key" TEXT NOT NULL, - "value" TEXT NOT NULL, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL, - "expiresAt" TIMESTAMP(3) NOT NULL, - - CONSTRAINT "GlobalLock_pkey" PRIMARY KEY ("key") -); - --- CreateTable -CREATE TABLE "RepeatKey" ( - "key" TEXT NOT NULL, - "value" TEXT NOT NULL, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "expiresAt" TIMESTAMP(3) NOT NULL, - - CONSTRAINT "RepeatKey_pkey" PRIMARY KEY ("key") -); - --- CreateTable -CREATE TABLE "SimpleCache" ( - "key" TEXT NOT NULL, - "value" TEXT NOT NULL, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL, - - CONSTRAINT "SimpleCache_pkey" PRIMARY KEY ("key") -); - --- CreateIndex -CREATE UNIQUE INDEX "Account_publicKey_key" ON "Account"("publicKey"); diff --git a/prisma/migrations/20250713004156_add_sessions/migration.sql b/prisma/migrations/20250713004156_add_sessions/migration.sql deleted file mode 100644 index b513bfc9..00000000 --- a/prisma/migrations/20250713004156_add_sessions/migration.sql +++ /dev/null @@ -1,46 +0,0 @@ --- AlterTable -ALTER TABLE "Account" ADD COLUMN "seq" INTEGER NOT NULL DEFAULT 0; - --- CreateTable -CREATE TABLE "Session" ( - "id" TEXT NOT NULL, - "accountId" TEXT NOT NULL, - "seq" INTEGER NOT NULL DEFAULT 0, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL, - - CONSTRAINT "Session_pkey" PRIMARY KEY ("id") -); - --- CreateTable -CREATE TABLE "SessionMessage" ( - "id" TEXT NOT NULL, - "sessionId" TEXT NOT NULL, - "seq" INTEGER NOT NULL, - "content" JSONB NOT NULL, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL, - - CONSTRAINT "SessionMessage_pkey" PRIMARY KEY ("id") -); - --- CreateTable -CREATE TABLE "Update" ( - "id" TEXT NOT NULL, - "accountId" TEXT NOT NULL, - "seq" INTEGER NOT NULL, - "content" JSONB NOT NULL, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL, - - CONSTRAINT "Update_pkey" PRIMARY KEY ("id") -); - --- AddForeignKey -ALTER TABLE "Session" ADD CONSTRAINT "Session_accountId_fkey" FOREIGN KEY ("accountId") REFERENCES "Account"("id") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "SessionMessage" ADD CONSTRAINT "SessionMessage_sessionId_fkey" FOREIGN KEY ("sessionId") REFERENCES "Session"("id") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "Update" ADD CONSTRAINT "Update_accountId_fkey" FOREIGN KEY ("accountId") REFERENCES "Account"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/prisma/migrations/20250713032124_add_tag_to_session/migration.sql b/prisma/migrations/20250713032124_add_tag_to_session/migration.sql deleted file mode 100644 index 01882c3f..00000000 --- a/prisma/migrations/20250713032124_add_tag_to_session/migration.sql +++ /dev/null @@ -1,12 +0,0 @@ -/* - Warnings: - - - A unique constraint covering the columns `[accountId,tag]` on the table `Session` will be added. If there are existing duplicate values, this will fail. - - Added the required column `tag` to the `Session` table without a default value. This is not possible if the table is not empty. - -*/ --- AlterTable -ALTER TABLE "Session" ADD COLUMN "tag" TEXT NOT NULL; - --- CreateIndex -CREATE UNIQUE INDEX "Session_accountId_tag_key" ON "Session"("accountId", "tag"); diff --git a/prisma/migrations/20250714030924_add_session_metadata/migration.sql b/prisma/migrations/20250714030924_add_session_metadata/migration.sql deleted file mode 100644 index d0cadc4d..00000000 --- a/prisma/migrations/20250714030924_add_session_metadata/migration.sql +++ /dev/null @@ -1,8 +0,0 @@ -/* - Warnings: - - - Added the required column `metadata` to the `Session` table without a default value. This is not possible if the table is not empty. - -*/ --- AlterTable -ALTER TABLE "Session" ADD COLUMN "metadata" TEXT NOT NULL; diff --git a/prisma/migrations/20250714032124_session_timeouts/migration.sql b/prisma/migrations/20250714032124_session_timeouts/migration.sql deleted file mode 100644 index a4c84514..00000000 --- a/prisma/migrations/20250714032124_session_timeouts/migration.sql +++ /dev/null @@ -1,3 +0,0 @@ --- AlterTable -ALTER TABLE "Session" ADD COLUMN "active" BOOLEAN NOT NULL DEFAULT true, -ADD COLUMN "lastActiveAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP; diff --git a/prisma/migrations/20250715012822_add_metadata_version_agent_state/migration.sql b/prisma/migrations/20250715012822_add_metadata_version_agent_state/migration.sql deleted file mode 100644 index a1490d86..00000000 --- a/prisma/migrations/20250715012822_add_metadata_version_agent_state/migration.sql +++ /dev/null @@ -1,4 +0,0 @@ --- AlterTable -ALTER TABLE "Session" ADD COLUMN "agentState" TEXT, -ADD COLUMN "agentStateVersion" INTEGER NOT NULL DEFAULT 0, -ADD COLUMN "metadataVersion" INTEGER NOT NULL DEFAULT 0; diff --git a/prisma/migrations/20250718031550_add_local_id_to_session_message/migration.sql b/prisma/migrations/20250718031550_add_local_id_to_session_message/migration.sql deleted file mode 100644 index b9f32cb6..00000000 --- a/prisma/migrations/20250718031550_add_local_id_to_session_message/migration.sql +++ /dev/null @@ -1,11 +0,0 @@ -/* - Warnings: - - - A unique constraint covering the columns `[sessionId,localId]` on the table `SessionMessage` will be added. If there are existing duplicate values, this will fail. - -*/ --- AlterTable -ALTER TABLE "SessionMessage" ADD COLUMN "localId" TEXT; - --- CreateIndex -CREATE UNIQUE INDEX "SessionMessage_sessionId_localId_key" ON "SessionMessage"("sessionId", "localId"); diff --git a/prisma/migrations/20250718032748_add_push_token/migration.sql b/prisma/migrations/20250718032748_add_push_token/migration.sql deleted file mode 100644 index a0468ada..00000000 --- a/prisma/migrations/20250718032748_add_push_token/migration.sql +++ /dev/null @@ -1,16 +0,0 @@ --- CreateTable -CREATE TABLE "AccountPushToken" ( - "id" TEXT NOT NULL, - "accountId" TEXT NOT NULL, - "token" TEXT NOT NULL, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL, - - CONSTRAINT "AccountPushToken_pkey" PRIMARY KEY ("id") -); - --- CreateIndex -CREATE UNIQUE INDEX "AccountPushToken_accountId_token_key" ON "AccountPushToken"("accountId", "token"); - --- AddForeignKey -ALTER TABLE "AccountPushToken" ADD CONSTRAINT "AccountPushToken_accountId_fkey" FOREIGN KEY ("accountId") REFERENCES "Account"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/prisma/migrations/20250719042829_add_terminal_auth_request/migration.sql b/prisma/migrations/20250719042829_add_terminal_auth_request/migration.sql deleted file mode 100644 index 7963f1c4..00000000 --- a/prisma/migrations/20250719042829_add_terminal_auth_request/migration.sql +++ /dev/null @@ -1,13 +0,0 @@ --- CreateTable -CREATE TABLE "TerminalAuthRequest" ( - "id" TEXT NOT NULL, - "publicKey" TEXT NOT NULL, - "response" TEXT, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL, - - CONSTRAINT "TerminalAuthRequest_pkey" PRIMARY KEY ("id") -); - --- CreateIndex -CREATE UNIQUE INDEX "TerminalAuthRequest_publicKey_key" ON "TerminalAuthRequest"("publicKey"); diff --git a/prisma/migrations/20250719061508_add_response_account/migration.sql b/prisma/migrations/20250719061508_add_response_account/migration.sql deleted file mode 100644 index a966b961..00000000 --- a/prisma/migrations/20250719061508_add_response_account/migration.sql +++ /dev/null @@ -1,5 +0,0 @@ --- AlterTable -ALTER TABLE "TerminalAuthRequest" ADD COLUMN "responseAccountId" TEXT; - --- AddForeignKey -ALTER TABLE "TerminalAuthRequest" ADD CONSTRAINT "TerminalAuthRequest_responseAccountId_fkey" FOREIGN KEY ("responseAccountId") REFERENCES "Account"("id") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/prisma/migrations/20250721073743_add_usage_report/migration.sql b/prisma/migrations/20250721073743_add_usage_report/migration.sql deleted file mode 100644 index 2afca773..00000000 --- a/prisma/migrations/20250721073743_add_usage_report/migration.sql +++ /dev/null @@ -1,27 +0,0 @@ --- CreateTable -CREATE TABLE "UsageReport" ( - "id" TEXT NOT NULL, - "key" TEXT NOT NULL, - "accountId" TEXT NOT NULL, - "sessionId" TEXT, - "data" JSONB NOT NULL, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL, - - CONSTRAINT "UsageReport_pkey" PRIMARY KEY ("id") -); - --- CreateIndex -CREATE INDEX "UsageReport_accountId_idx" ON "UsageReport"("accountId"); - --- CreateIndex -CREATE INDEX "UsageReport_sessionId_idx" ON "UsageReport"("sessionId"); - --- CreateIndex -CREATE UNIQUE INDEX "UsageReport_accountId_sessionId_key_key" ON "UsageReport"("accountId", "sessionId", "key"); - --- AddForeignKey -ALTER TABLE "UsageReport" ADD CONSTRAINT "UsageReport_accountId_fkey" FOREIGN KEY ("accountId") REFERENCES "Account"("id") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "UsageReport" ADD CONSTRAINT "UsageReport_sessionId_fkey" FOREIGN KEY ("sessionId") REFERENCES "Session"("id") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/prisma/migrations/20250726092110_remove_updates/migration.sql b/prisma/migrations/20250726092110_remove_updates/migration.sql deleted file mode 100644 index 5074ac13..00000000 --- a/prisma/migrations/20250726092110_remove_updates/migration.sql +++ /dev/null @@ -1,11 +0,0 @@ -/* - Warnings: - - - You are about to drop the `Update` table. If the table is not empty, all the data it contains will be lost. - -*/ --- DropForeignKey -ALTER TABLE "Update" DROP CONSTRAINT "Update_accountId_fkey"; - --- DropTable -DROP TABLE "Update"; diff --git a/prisma/migrations/20250726205102_add_settings_to_account/migration.sql b/prisma/migrations/20250726205102_add_settings_to_account/migration.sql deleted file mode 100644 index 9b2a5a3c..00000000 --- a/prisma/migrations/20250726205102_add_settings_to_account/migration.sql +++ /dev/null @@ -1,2 +0,0 @@ --- AlterTable -ALTER TABLE "Account" ADD COLUMN "settings" TEXT; diff --git a/prisma/migrations/20250726205206_add_account_settings_version/migration.sql b/prisma/migrations/20250726205206_add_account_settings_version/migration.sql deleted file mode 100644 index 4a916269..00000000 --- a/prisma/migrations/20250726205206_add_account_settings_version/migration.sql +++ /dev/null @@ -1,2 +0,0 @@ --- AlterTable -ALTER TABLE "Account" ADD COLUMN "settingsVersion" INTEGER NOT NULL DEFAULT 0; diff --git a/prisma/migrations/20250812092041_add_machine_model/migration.sql b/prisma/migrations/20250812092041_add_machine_model/migration.sql deleted file mode 100644 index 1e06047c..00000000 --- a/prisma/migrations/20250812092041_add_machine_model/migration.sql +++ /dev/null @@ -1,23 +0,0 @@ --- CreateTable -CREATE TABLE "Machine" ( - "id" TEXT NOT NULL, - "accountId" TEXT NOT NULL, - "metadata" TEXT NOT NULL, - "metadataVersion" INTEGER NOT NULL DEFAULT 0, - "seq" INTEGER NOT NULL DEFAULT 0, - "active" BOOLEAN NOT NULL DEFAULT true, - "lastActiveAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL, - - CONSTRAINT "Machine_pkey" PRIMARY KEY ("id") -); - --- CreateIndex -CREATE INDEX "Machine_accountId_idx" ON "Machine"("accountId"); - --- CreateIndex -CREATE UNIQUE INDEX "Machine_accountId_id_key" ON "Machine"("accountId", "id"); - --- AddForeignKey -ALTER TABLE "Machine" ADD CONSTRAINT "Machine_accountId_fkey" FOREIGN KEY ("accountId") REFERENCES "Account"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/prisma/migrations/20250816171155_add_app_to_app_authentication/migration.sql b/prisma/migrations/20250816171155_add_app_to_app_authentication/migration.sql deleted file mode 100644 index 14e7cd7b..00000000 --- a/prisma/migrations/20250816171155_add_app_to_app_authentication/migration.sql +++ /dev/null @@ -1,17 +0,0 @@ --- CreateTable -CREATE TABLE "AccountAuthRequest" ( - "id" TEXT NOT NULL, - "publicKey" TEXT NOT NULL, - "response" TEXT, - "responseAccountId" TEXT, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL, - - CONSTRAINT "AccountAuthRequest_pkey" PRIMARY KEY ("id") -); - --- CreateIndex -CREATE UNIQUE INDEX "AccountAuthRequest_publicKey_key" ON "AccountAuthRequest"("publicKey"); - --- AddForeignKey -ALTER TABLE "AccountAuthRequest" ADD CONSTRAINT "AccountAuthRequest_responseAccountId_fkey" FOREIGN KEY ("responseAccountId") REFERENCES "Account"("id") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/prisma/migrations/20250818044258_add_daemon_state_to_machine/migration.sql b/prisma/migrations/20250818044258_add_daemon_state_to_machine/migration.sql deleted file mode 100644 index ff78ad35..00000000 --- a/prisma/migrations/20250818044258_add_daemon_state_to_machine/migration.sql +++ /dev/null @@ -1,3 +0,0 @@ --- AlterTable -ALTER TABLE "Machine" ADD COLUMN "daemonState" TEXT, -ADD COLUMN "daemonStateVersion" INTEGER NOT NULL DEFAULT 0; diff --git a/prisma/migrations/20250820051609_add_session_id_seq_index/migration.sql b/prisma/migrations/20250820051609_add_session_id_seq_index/migration.sql deleted file mode 100644 index 3db604c6..00000000 --- a/prisma/migrations/20250820051609_add_session_id_seq_index/migration.sql +++ /dev/null @@ -1,2 +0,0 @@ --- CreateIndex -CREATE INDEX "SessionMessage_sessionId_seq_idx" ON "SessionMessage"("sessionId", "seq"); diff --git a/prisma/migrations/20250820052449_add_session_sort/migration.sql b/prisma/migrations/20250820052449_add_session_sort/migration.sql deleted file mode 100644 index 57e02cf4..00000000 --- a/prisma/migrations/20250820052449_add_session_sort/migration.sql +++ /dev/null @@ -1,2 +0,0 @@ --- CreateIndex -CREATE INDEX "Session_accountId_updatedAt_idx" ON "Session"("accountId", "updatedAt" DESC); diff --git a/prisma/migrations/20250827015520_add_github_entities/migration.sql b/prisma/migrations/20250827015520_add_github_entities/migration.sql deleted file mode 100644 index cc6a2994..00000000 --- a/prisma/migrations/20250827015520_add_github_entities/migration.sql +++ /dev/null @@ -1,26 +0,0 @@ --- AlterTable -ALTER TABLE "Account" ADD COLUMN "githubUserId" TEXT; - --- CreateTable -CREATE TABLE "GithubUser" ( - "id" TEXT NOT NULL, - "profile" JSONB NOT NULL, - "token" BYTEA, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL, - - CONSTRAINT "GithubUser_pkey" PRIMARY KEY ("id") -); - --- CreateTable -CREATE TABLE "GithubOrganization" ( - "id" TEXT NOT NULL, - "profile" JSONB NOT NULL, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL, - - CONSTRAINT "GithubOrganization_pkey" PRIMARY KEY ("id") -); - --- AddForeignKey -ALTER TABLE "Account" ADD CONSTRAINT "Account_githubUserId_fkey" FOREIGN KEY ("githubUserId") REFERENCES "GithubUser"("id") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/prisma/migrations/20250827044624_add_user_profile_fields/migration.sql b/prisma/migrations/20250827044624_add_user_profile_fields/migration.sql deleted file mode 100644 index 1413723c..00000000 --- a/prisma/migrations/20250827044624_add_user_profile_fields/migration.sql +++ /dev/null @@ -1,24 +0,0 @@ --- AlterTable -ALTER TABLE "Account" ADD COLUMN "avatar" JSONB, -ADD COLUMN "firstName" TEXT, -ADD COLUMN "lastName" TEXT; - --- CreateTable -CREATE TABLE "UploadedFile" ( - "id" TEXT NOT NULL, - "accountId" TEXT NOT NULL, - "path" TEXT NOT NULL, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL, - - CONSTRAINT "UploadedFile_pkey" PRIMARY KEY ("id") -); - --- CreateIndex -CREATE INDEX "UploadedFile_accountId_idx" ON "UploadedFile"("accountId"); - --- CreateIndex -CREATE UNIQUE INDEX "UploadedFile_accountId_path_key" ON "UploadedFile"("accountId", "path"); - --- AddForeignKey -ALTER TABLE "UploadedFile" ADD CONSTRAINT "UploadedFile_accountId_fkey" FOREIGN KEY ("accountId") REFERENCES "Account"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/prisma/migrations/20250827045037_add_reuse_key_to_file/migration.sql b/prisma/migrations/20250827045037_add_reuse_key_to_file/migration.sql deleted file mode 100644 index a4681ba6..00000000 --- a/prisma/migrations/20250827045037_add_reuse_key_to_file/migration.sql +++ /dev/null @@ -1,2 +0,0 @@ --- AlterTable -ALTER TABLE "UploadedFile" ADD COLUMN "reuseKey" TEXT; diff --git a/prisma/migrations/20250827051355_add_image_parameters/migration.sql b/prisma/migrations/20250827051355_add_image_parameters/migration.sql deleted file mode 100644 index ee6482e3..00000000 --- a/prisma/migrations/20250827051355_add_image_parameters/migration.sql +++ /dev/null @@ -1,4 +0,0 @@ --- AlterTable -ALTER TABLE "UploadedFile" ADD COLUMN "height" INTEGER, -ADD COLUMN "thumbhash" TEXT, -ADD COLUMN "width" INTEGER; diff --git a/prisma/migrations/20250901205028_add_service_account_tokens/migration.sql b/prisma/migrations/20250901205028_add_service_account_tokens/migration.sql deleted file mode 100644 index 267bcad9..00000000 --- a/prisma/migrations/20250901205028_add_service_account_tokens/migration.sql +++ /dev/null @@ -1,22 +0,0 @@ --- CreateTable -CREATE TABLE "ServiceAccountToken" ( - "id" TEXT NOT NULL, - "accountId" TEXT NOT NULL, - "vendor" TEXT NOT NULL, - "token" BYTEA NOT NULL, - "metadata" JSONB, - "lastUsedAt" TIMESTAMP(3), - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL, - - CONSTRAINT "ServiceAccountToken_pkey" PRIMARY KEY ("id") -); - --- CreateIndex -CREATE INDEX "ServiceAccountToken_accountId_idx" ON "ServiceAccountToken"("accountId"); - --- CreateIndex -CREATE UNIQUE INDEX "ServiceAccountToken_accountId_vendor_key" ON "ServiceAccountToken"("accountId", "vendor"); - --- AddForeignKey -ALTER TABLE "ServiceAccountToken" ADD CONSTRAINT "ServiceAccountToken_accountId_fkey" FOREIGN KEY ("accountId") REFERENCES "Account"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/prisma/migrations/20250908050408_add_data_encryption_key/migration.sql b/prisma/migrations/20250908050408_add_data_encryption_key/migration.sql deleted file mode 100644 index dd5c399d..00000000 --- a/prisma/migrations/20250908050408_add_data_encryption_key/migration.sql +++ /dev/null @@ -1,2 +0,0 @@ --- AlterTable -ALTER TABLE "Session" ADD COLUMN "dataEncryptionKey" BYTEA; diff --git a/prisma/migrations/20250908052114_add_machine_data_encryption_key/migration.sql b/prisma/migrations/20250908052114_add_machine_data_encryption_key/migration.sql deleted file mode 100644 index 86b75da7..00000000 --- a/prisma/migrations/20250908052114_add_machine_data_encryption_key/migration.sql +++ /dev/null @@ -1,2 +0,0 @@ --- AlterTable -ALTER TABLE "Machine" ADD COLUMN "dataEncryptionKey" BYTEA; diff --git a/prisma/migrations/20250911030241_add_version2_field/migration.sql b/prisma/migrations/20250911030241_add_version2_field/migration.sql deleted file mode 100644 index e7c1bffa..00000000 --- a/prisma/migrations/20250911030241_add_version2_field/migration.sql +++ /dev/null @@ -1,2 +0,0 @@ --- AlterTable -ALTER TABLE "TerminalAuthRequest" ADD COLUMN "supportsV2" BOOLEAN NOT NULL DEFAULT false; diff --git a/prisma/migrations/20250917052000_add_artefacts/migration.sql b/prisma/migrations/20250917052000_add_artefacts/migration.sql deleted file mode 100644 index 143b692e..00000000 --- a/prisma/migrations/20250917052000_add_artefacts/migration.sql +++ /dev/null @@ -1,24 +0,0 @@ --- CreateTable -CREATE TABLE "Artifact" ( - "id" TEXT NOT NULL, - "accountId" TEXT NOT NULL, - "header" BYTEA NOT NULL, - "headerVersion" INTEGER NOT NULL DEFAULT 0, - "body" BYTEA NOT NULL, - "bodyVersion" INTEGER NOT NULL DEFAULT 0, - "dataEncryptionKey" BYTEA NOT NULL, - "seq" INTEGER NOT NULL DEFAULT 0, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL, - - CONSTRAINT "Artifact_pkey" PRIMARY KEY ("id") -); - --- CreateIndex -CREATE INDEX "Artifact_accountId_idx" ON "Artifact"("accountId"); - --- CreateIndex -CREATE INDEX "Artifact_accountId_updatedAt_idx" ON "Artifact"("accountId", "updatedAt" DESC); - --- AddForeignKey -ALTER TABLE "Artifact" ADD CONSTRAINT "Artifact_accountId_fkey" FOREIGN KEY ("accountId") REFERENCES "Account"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/prisma/migrations/20250917055002_add_access_key/migration.sql b/prisma/migrations/20250917055002_add_access_key/migration.sql deleted file mode 100644 index 89aaa435..00000000 --- a/prisma/migrations/20250917055002_add_access_key/migration.sql +++ /dev/null @@ -1,34 +0,0 @@ --- CreateTable -CREATE TABLE "AccessKey" ( - "id" TEXT NOT NULL, - "accountId" TEXT NOT NULL, - "machineId" TEXT NOT NULL, - "sessionId" TEXT NOT NULL, - "data" TEXT NOT NULL, - "dataVersion" INTEGER NOT NULL DEFAULT 0, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL, - - CONSTRAINT "AccessKey_pkey" PRIMARY KEY ("id") -); - --- CreateIndex -CREATE INDEX "AccessKey_accountId_idx" ON "AccessKey"("accountId"); - --- CreateIndex -CREATE INDEX "AccessKey_sessionId_idx" ON "AccessKey"("sessionId"); - --- CreateIndex -CREATE INDEX "AccessKey_machineId_idx" ON "AccessKey"("machineId"); - --- CreateIndex -CREATE UNIQUE INDEX "AccessKey_accountId_machineId_sessionId_key" ON "AccessKey"("accountId", "machineId", "sessionId"); - --- AddForeignKey -ALTER TABLE "AccessKey" ADD CONSTRAINT "AccessKey_accountId_fkey" FOREIGN KEY ("accountId") REFERENCES "Account"("id") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "AccessKey" ADD CONSTRAINT "AccessKey_accountId_machineId_fkey" FOREIGN KEY ("accountId", "machineId") REFERENCES "Machine"("accountId", "id") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "AccessKey" ADD CONSTRAINT "AccessKey_sessionId_fkey" FOREIGN KEY ("sessionId") REFERENCES "Session"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/prisma/migrations/20250918045344_add_friendships/migration.sql b/prisma/migrations/20250918045344_add_friendships/migration.sql deleted file mode 100644 index cedee535..00000000 --- a/prisma/migrations/20250918045344_add_friendships/migration.sql +++ /dev/null @@ -1,26 +0,0 @@ --- CreateEnum -CREATE TYPE "RelationshipStatus" AS ENUM ('pending', 'accepted', 'rejected', 'removed'); - --- CreateTable -CREATE TABLE "UserRelationship" ( - "fromUserId" TEXT NOT NULL, - "toUserId" TEXT NOT NULL, - "status" "RelationshipStatus" NOT NULL DEFAULT 'pending', - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL, - "acceptedAt" TIMESTAMP(3), - - CONSTRAINT "UserRelationship_pkey" PRIMARY KEY ("fromUserId","toUserId") -); - --- CreateIndex -CREATE INDEX "UserRelationship_toUserId_status_idx" ON "UserRelationship"("toUserId", "status"); - --- CreateIndex -CREATE INDEX "UserRelationship_fromUserId_status_idx" ON "UserRelationship"("fromUserId", "status"); - --- AddForeignKey -ALTER TABLE "UserRelationship" ADD CONSTRAINT "UserRelationship_fromUserId_fkey" FOREIGN KEY ("fromUserId") REFERENCES "Account"("id") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "UserRelationship" ADD CONSTRAINT "UserRelationship_toUserId_fkey" FOREIGN KEY ("toUserId") REFERENCES "Account"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/prisma/migrations/20250919021354_fix_relationship_status/migration.sql b/prisma/migrations/20250919021354_fix_relationship_status/migration.sql deleted file mode 100644 index 3e57f760..00000000 --- a/prisma/migrations/20250919021354_fix_relationship_status/migration.sql +++ /dev/null @@ -1,16 +0,0 @@ -/* - Warnings: - - - The values [accepted,removed] on the enum `RelationshipStatus` will be removed. If these variants are still used in the database, this will fail. - -*/ --- AlterEnum -BEGIN; -CREATE TYPE "RelationshipStatus_new" AS ENUM ('none', 'requested', 'pending', 'friend', 'rejected'); -ALTER TABLE "UserRelationship" ALTER COLUMN "status" DROP DEFAULT; -ALTER TABLE "UserRelationship" ALTER COLUMN "status" TYPE "RelationshipStatus_new" USING ("status"::text::"RelationshipStatus_new"); -ALTER TYPE "RelationshipStatus" RENAME TO "RelationshipStatus_old"; -ALTER TYPE "RelationshipStatus_new" RENAME TO "RelationshipStatus"; -DROP TYPE "RelationshipStatus_old"; -ALTER TABLE "UserRelationship" ALTER COLUMN "status" SET DEFAULT 'pending'; -COMMIT; diff --git a/prisma/migrations/20250920025406_add_username/migration.sql b/prisma/migrations/20250920025406_add_username/migration.sql deleted file mode 100644 index 8507d5a3..00000000 --- a/prisma/migrations/20250920025406_add_username/migration.sql +++ /dev/null @@ -1,11 +0,0 @@ -/* - Warnings: - - - A unique constraint covering the columns `[username]` on the table `Account` will be added. If there are existing duplicate values, this will fail. - -*/ --- AlterTable -ALTER TABLE "Account" ADD COLUMN "username" TEXT; - --- CreateIndex -CREATE UNIQUE INDEX "Account_username_key" ON "Account"("username"); diff --git a/prisma/migrations/20250920035415_make_github_user_id_unique/migration.sql b/prisma/migrations/20250920035415_make_github_user_id_unique/migration.sql deleted file mode 100644 index 7922a0d8..00000000 --- a/prisma/migrations/20250920035415_make_github_user_id_unique/migration.sql +++ /dev/null @@ -1,8 +0,0 @@ -/* - Warnings: - - - A unique constraint covering the columns `[githubUserId]` on the table `Account` will be added. If there are existing duplicate values, this will fail. - -*/ --- CreateIndex -CREATE UNIQUE INDEX "Account_githubUserId_key" ON "Account"("githubUserId"); diff --git a/prisma/migrations/20250920213557_add_user_feed/migration.sql b/prisma/migrations/20250920213557_add_user_feed/migration.sql deleted file mode 100644 index 4ae72b92..00000000 --- a/prisma/migrations/20250920213557_add_user_feed/migration.sql +++ /dev/null @@ -1,27 +0,0 @@ --- AlterTable -ALTER TABLE "Account" ADD COLUMN "feedSeq" BIGINT NOT NULL DEFAULT 0; - --- CreateTable -CREATE TABLE "UserFeedItem" ( - "id" TEXT NOT NULL, - "userId" TEXT NOT NULL, - "counter" BIGINT NOT NULL, - "repeatKey" TEXT, - "body" JSONB NOT NULL, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL, - - CONSTRAINT "UserFeedItem_pkey" PRIMARY KEY ("id") -); - --- CreateIndex -CREATE INDEX "UserFeedItem_userId_counter_idx" ON "UserFeedItem"("userId", "counter" DESC); - --- CreateIndex -CREATE UNIQUE INDEX "UserFeedItem_userId_counter_key" ON "UserFeedItem"("userId", "counter"); - --- CreateIndex -CREATE UNIQUE INDEX "UserFeedItem_userId_repeatKey_key" ON "UserFeedItem"("userId", "repeatKey"); - --- AddForeignKey -ALTER TABLE "UserFeedItem" ADD CONSTRAINT "UserFeedItem_userId_fkey" FOREIGN KEY ("userId") REFERENCES "Account"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/prisma/migrations/20250920215413_add_last_notified_at/migration.sql b/prisma/migrations/20250920215413_add_last_notified_at/migration.sql deleted file mode 100644 index ab59469f..00000000 --- a/prisma/migrations/20250920215413_add_last_notified_at/migration.sql +++ /dev/null @@ -1,2 +0,0 @@ --- AlterTable -ALTER TABLE "UserRelationship" ADD COLUMN "lastNotifiedAt" TIMESTAMP(3); diff --git a/prisma/migrations/20250922000310_add_user_kv/migration.sql b/prisma/migrations/20250922000310_add_user_kv/migration.sql deleted file mode 100644 index 791ca300..00000000 --- a/prisma/migrations/20250922000310_add_user_kv/migration.sql +++ /dev/null @@ -1,21 +0,0 @@ --- CreateTable -CREATE TABLE "UserKVStore" ( - "id" TEXT NOT NULL, - "accountId" TEXT NOT NULL, - "key" TEXT NOT NULL, - "value" BYTEA, - "version" INTEGER NOT NULL DEFAULT 0, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL, - - CONSTRAINT "UserKVStore_pkey" PRIMARY KEY ("id") -); - --- CreateIndex -CREATE INDEX "UserKVStore_accountId_idx" ON "UserKVStore"("accountId"); - --- CreateIndex -CREATE UNIQUE INDEX "UserKVStore_accountId_key_key" ON "UserKVStore"("accountId", "key"); - --- AddForeignKey -ALTER TABLE "UserKVStore" ADD CONSTRAINT "UserKVStore_accountId_fkey" FOREIGN KEY ("accountId") REFERENCES "Account"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/prisma/migrations/migration_lock.toml b/prisma/migrations/migration_lock.toml deleted file mode 100644 index 044d57cd..00000000 --- a/prisma/migrations/migration_lock.toml +++ /dev/null @@ -1,3 +0,0 @@ -# Please do not edit this file manually -# It should be added in your version-control system (e.g., Git) -provider = "postgresql" diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 63493058..349a98fd 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -3,7 +3,7 @@ generator client { provider = "prisma-client-js" - previewFeatures = ["metrics", "relationJoins"] + previewFeatures = ["metrics"] } generator json { @@ -11,7 +11,7 @@ generator json { } datasource db { - provider = "postgresql" + provider = "sqlite" url = env("DATABASE_URL") } @@ -110,7 +110,7 @@ model Session { accessKeys AccessKey[] @@unique([accountId, tag]) - @@index([accountId, updatedAt(sort: Desc)]) + @@index([accountId, updatedAt]) } model SessionMessage { @@ -270,7 +270,7 @@ model Artifact { updatedAt DateTime @updatedAt @@index([accountId]) - @@index([accountId, updatedAt(sort: Desc)]) + @@index([accountId, updatedAt]) } // @@ -341,7 +341,7 @@ model UserFeedItem { @@unique([userId, counter]) @@unique([userId, repeatKey]) - @@index([userId, counter(sort: Desc)]) + @@index([userId, counter]) } // diff --git a/sources/app/api/routes/userRoutes.ts b/sources/app/api/routes/userRoutes.ts index 9da42393..026fa2b9 100644 --- a/sources/app/api/routes/userRoutes.ts +++ b/sources/app/api/routes/userRoutes.ts @@ -75,11 +75,11 @@ export async function userRoutes(app: Fastify) { const { query } = request.query; // Search for users by username, first 10 matches + // Note: SQLite doesn't support case-insensitive mode, using case-sensitive search const users = await db.account.findMany({ where: { username: { - startsWith: query, - mode: 'insensitive' + startsWith: query } }, include: { diff --git a/sources/storage/inTx.ts b/sources/storage/inTx.ts index 0f85e720..b2a90f2d 100644 --- a/sources/storage/inTx.ts +++ b/sources/storage/inTx.ts @@ -21,7 +21,7 @@ export async function inTx(fn: (tx: Tx) => Promise): Promise { } while (true) { try { - let result = await db.$transaction(wrapped, { isolationLevel: 'Serializable', timeout: 10000 }); + let result = await db.$transaction(wrapped, { timeout: 10000 }); for (let callback of result.callbacks) { try { callback(); From 650e9b927e937eab28068487f161db983f200ad0 Mon Sep 17 00:00:00 2001 From: Oliver Marshall Date: Sat, 31 Jan 2026 09:39:57 +0000 Subject: [PATCH 4/5] fix: auto-create SQLite tables on startup - Copy prisma schema to runtime container - Run prisma db push before starting server (idempotent) Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude Co-Authored-By: Happy --- Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 2e620e84..f3f09735 100644 --- a/Dockerfile +++ b/Dockerfile @@ -37,9 +37,11 @@ COPY --from=builder /app/tsconfig.json ./tsconfig.json COPY --from=builder /app/package.json ./package.json COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/sources ./sources +COPY --from=builder /app/prisma ./prisma # Expose the port the app will run on EXPOSE 3000 # Command to run the application -CMD ["yarn", "start"] \ No newline at end of file +# prisma db push creates tables if they don't exist (idempotent) +CMD ["sh", "-c", "npx prisma db push --skip-generate && yarn start"] \ No newline at end of file From 81c860376a4e05b3cf484b218c55dd87b5d5d819 Mon Sep 17 00:00:00 2001 From: Oliver Marshall Date: Sat, 31 Jan 2026 11:23:07 +0000 Subject: [PATCH 5/5] docs: add Fly.io deployment with Litestream backup - Add fly.toml configuration - Add deployment instructions to README - Include Litestream for continuous SQLite backup to Tigris - Add cost estimates (~$1.50-3/month) Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude Co-Authored-By: Happy --- .dockerignore | 11 ++ README.md | 152 ++++++++++++++++--- dbsetup.js | 38 +++++ fly.toml | 38 +++++ package.json | 5 + yarn.lock | 411 +++++++++++++++++++++++++++++++++++++++++++++++++- 6 files changed, 634 insertions(+), 21 deletions(-) create mode 100644 .dockerignore create mode 100755 dbsetup.js create mode 100644 fly.toml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..c2df10da --- /dev/null +++ b/.dockerignore @@ -0,0 +1,11 @@ +node_modules +.env +.env.local +dist + +# SQLite database +*.db +*.db-journal + +.logs/ +.claude/ diff --git a/README.md b/README.md index bef4da68..1ed498fb 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,147 @@ -# Happy Server +# Happy Server (Lite) -Minimal backend for open-source end-to-end encrypted Claude Code clients. +A slimmed-down fork of [Happy Server](https://github.com/anthropics/happy-server) - the synchronization backend for end-to-end encrypted Claude Code clients. -## What is Happy? +This version removes external dependencies (PostgreSQL, Redis, MinIO) in favor of a single SQLite database file, making it trivial to self-host. -Happy Server is the synchronization backbone for secure Claude Code clients. It enables multiple devices to share encrypted conversations while maintaining complete privacy - the server never sees your messages, only encrypted blobs it cannot read. +## What Changed + +| Original | This Fork | +|----------|-----------| +| PostgreSQL | SQLite | +| Redis | Removed (unused) | +| MinIO/S3 | Removed (uses GitHub avatar URLs directly) | +| Multiple containers | Single process + file | ## Features -- 🔐 **Zero Knowledge** - The server stores encrypted data but has no ability to decrypt it -- 🎯 **Minimal Surface** - Only essential features for secure sync, nothing more -- 🕵️ **Privacy First** - No analytics, no tracking, no data mining -- 📖 **Open Source** - Transparent implementation you can audit and self-host -- 🔑 **Cryptographic Auth** - No passwords stored, only public key signatures -- ⚡ **Real-time Sync** - WebSocket-based synchronization across all your devices -- 📱 **Multi-device** - Seamless session management across phones, tablets, and computers -- 🔔 **Push Notifications** - Notify when Claude Code finishes tasks or needs permissions (encrypted, we can't see the content) -- 🌐 **Distributed Ready** - Built to scale horizontally when needed +- **Zero Knowledge** - Server stores encrypted data it cannot decrypt +- **Single File Database** - Just SQLite, no external dependencies +- **Easy Self-Hosting** - Deploy anywhere that runs Node.js +- **Real-time Sync** - WebSocket-based sync across devices +- **Cryptographic Auth** - Public key signatures, no passwords + +## Requirements + +- Node.js 20+ +- Yarn + +## Local Development + +```bash +# Install dependencies +yarn install + +# Create database and start server +yarn db:push +yarn dev +``` + +Server runs at `http://localhost:3005` + +## Self-Hosting + +### Option 1: Fly.io (Recommended) + +**Cost estimate:** ~$1.50/month (8 hours/day usage) or ~$3.15/month (always on) + +| Resource | Always On | 8 hrs/day | +|----------|-----------|-----------| +| VM (shared-cpu-1x, 512MB) | $2.68/mo | ~$1.35/mo | +| Volume (1GB) | $0.15/mo | $0.15/mo | +| **Total** | **~$3/mo** | **~$1.50/mo** | + +The server auto-scales to zero when no clients are connected. Note: WebSocket connections (mobile app, CLI daemons) keep the server running. It only scales down when all clients disconnect. + +**Deployment:** + +```bash +# Install Fly CLI and authenticate +brew install flyctl +fly auth login + +# Launch app +fly launch --no-deploy +``` + +When prompted: +- **App name:** Choose a name (e.g., `happy-server`) +- **Region:** Pick one close to you (e.g., `lhr` for London) +- **PostgreSQL/Redis:** No (we use SQLite) + +```bash +# Create persistent volume for SQLite database +fly volumes create happy_data --region lhr --size 1 + +# Set your master secret (used for internal encryption) +fly secrets set HANDY_MASTER_SECRET="$(openssl rand -base64 32)" + +# Deploy +fly deploy +``` + +**Custom domain (optional):** + +```bash +fly certs add your-domain.com +``` + +Then add a DNS record: +- **CNAME:** `your-domain.com` → `your-app.fly.dev` + +### Option 2: Any VPS / Docker + +```bash +# Build +docker build -t happy-server . + +# Run with persistent volume +docker run -d \ + -p 3000:3000 \ + -v happy_data:/data \ + -e DATABASE_URL="file:/data/happy.db" \ + -e HANDY_MASTER_SECRET="your-secret-here" \ + happy-server +``` + +### Option 3: Coolify / Railway / etc. + +Set these environment variables: +- `DATABASE_URL=file:/data/happy.db` +- `HANDY_MASTER_SECRET=` +- `PORT=3000` -## How It Works +Mount a persistent volume at `/data`. -Your Claude Code clients generate encryption keys locally and use Happy Server as a secure relay. Messages are end-to-end encrypted before leaving your device. The server's job is simple: store encrypted blobs and sync them between your devices in real-time. +## Environment Variables -## Hosting +| Variable | Required | Description | +|----------|----------|-------------| +| `DATABASE_URL` | Yes | SQLite path, e.g. `file:/data/happy.db` | +| `HANDY_MASTER_SECRET` | Yes | Secret for internal encryption (OAuth tokens, etc.) | +| `PORT` | No | Server port (default: 3000) | +| `METRICS_ENABLED` | No | Enable Prometheus metrics (default: false) | -**You don't need to self-host!** Our free cloud Happy Server at `happy-api.slopus.com` is just as secure as running your own. Since all data is end-to-end encrypted before it reaches our servers, we literally cannot read your messages even if we wanted to. The encryption happens on your device, and only you have the keys. +## Architecture -That said, Happy Server is open source and self-hostable if you prefer running your own infrastructure. The security model is identical whether you use our servers or your own. +``` +┌─────────────────┐ ┌─────────────────┐ +│ Mobile App │ │ CLI Daemon │ +│ (has master │ │ (encrypts all │ +│ keypair) │ │ data locally) │ +└────────┬────────┘ └────────┬────────┘ + │ │ + │ encrypted blobs │ + ▼ ▼ +┌─────────────────────────────────────────┐ +│ Happy Server │ +│ │ +│ • Stores encrypted data it can't read │ +│ • Syncs between devices via WebSocket │ +│ • Single SQLite file │ +└─────────────────────────────────────────┘ +``` ## License -MIT - Use it, modify it, deploy it anywhere. \ No newline at end of file +MIT diff --git a/dbsetup.js b/dbsetup.js new file mode 100755 index 00000000..959c9135 --- /dev/null +++ b/dbsetup.js @@ -0,0 +1,38 @@ +#!/usr/bin/env node + +import { spawn } from 'node:child_process' +import fs from 'node:fs' + +const env = { ...process.env } + +const url = new URL(process.env.DATABASE_URL) +const target = url.protocol === 'file:' && url.pathname + +// restore database if not present and replica exists +const newDb = target && !fs.existsSync(target) +if (newDb && process.env.BUCKET_NAME) { + await exec(`npx litestream restore -config litestream.yml -if-replica-exists ${target}`) +} + +// prepare database +await exec('npx prisma migrate deploy') + +// launch application +if (process.env.BUCKET_NAME) { + await exec(`npx litestream replicate -config litestream.yml -exec ${JSON.stringify(process.argv.slice(2).join(' '))}`) +} else { + await exec(process.argv.slice(2).join(' ')) +} + +function exec(command) { + const child = spawn(command, { shell: true, stdio: 'inherit', env }) + return new Promise((resolve, reject) => { + child.on('exit', code => { + if (code === 0) { + resolve() + } else { + reject(new Error(`${command} failed rc=${code}`)) + } + }) + }) +} diff --git a/fly.toml b/fly.toml new file mode 100644 index 00000000..7c0200aa --- /dev/null +++ b/fly.toml @@ -0,0 +1,38 @@ +# fly.toml app configuration file generated for happy-server-billowing-dawn-6678 on 2026-01-31T10:58:39Z +# +# See https://fly.io/docs/reference/configuration/ for information about how to use this file. +# + +app = 'happy-server-billowing-dawn-6678' +primary_region = 'lhr' + +[build] + +[env] + DATABASE_URL = 'file:/data/happy.db' + METRICS_ENABLED = 'false' + NODE_ENV = 'production' + PORT = '3000' + +[[mounts]] + source = 'happy_data' + destination = '/data' + +[http_service] + internal_port = 3000 + force_https = true + auto_stop_machines = 'stop' + auto_start_machines = true + min_machines_running = 0 + processes = ['app'] + + [http_service.concurrency] + type = 'connections' + hard_limit = 250 + soft_limit = 200 + +[[vm]] + memory = '512mb' + cpu_kind = 'shared' + cpus = 1 + memory_mb = 512 diff --git a/package.json b/package.json index 61cc607b..fa9f80f9 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "postinstall": "prisma generate" }, "devDependencies": { + "@flydotio/dockerfile": "^0.7.10", "@types/chalk": "^2.2.0", "@types/express": "^4.17.21", "@types/node": "^20.12.3", @@ -31,6 +32,7 @@ "@date-fns/tz": "^1.2.0", "@fastify/bearer-auth": "^10.1.1", "@fastify/cors": "^10.0.1", + "@flydotio/litestream": "^1.0.1", "@prisma/client": "^6.11.1", "@types/jsonwebtoken": "^9.0.10", "@types/semver": "^7.7.0", @@ -59,5 +61,8 @@ "vitest": "^3.2.0", "zod": "^3.24.2", "zod-to-json-schema": "^3.24.3" + }, + "dockerfile": { + "litestream": true } } diff --git a/yarn.lock b/yarn.lock index 90b3252d..8af93bf3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -324,6 +324,193 @@ "@fastify/forwarded" "^3.0.0" ipaddr.js "^2.1.0" +"@flydotio/dockerfile@^0.7.10": + version "0.7.10" + resolved "https://registry.yarnpkg.com/@flydotio/dockerfile/-/dockerfile-0.7.10.tgz#e18c678e5ae6da54848aeaa702762d11a1bcb79b" + integrity sha512-dTXqBjCl7nFmnhlyeDjjPtX+sdfYBWFH9PUKNqAYttvBiczKcYXxr7/0A0wZ+g1FB1tmMzsOzedgr6xap/AB9g== + dependencies: + chalk "^5.4.1" + diff "^7.0.0" + ejs "^3.1.10" + inquirer "^12.4.1" + shell-quote "^1.8.2" + yargs "^17.7.2" + +"@flydotio/litestream-darwin-arm64@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@flydotio/litestream-darwin-arm64/-/litestream-darwin-arm64-1.0.1.tgz#8cb385a63a3e38fab280f14fa037837bcf6abd09" + integrity sha512-LI663pEbO1RZzzkqDbXen6UIDeOBkGJqfyl8FGm4Y+zbcKiLQhopuQLMs4BHlWelGMb2ZnwpcpM+OcimoDhqHA== + +"@flydotio/litestream-darwin-x64@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@flydotio/litestream-darwin-x64/-/litestream-darwin-x64-1.0.1.tgz#4f4d9df79e3b4fa55cb7708019e39c084b476913" + integrity sha512-AecPpC1mu5QJ12+UWEaeCZbtNbde+t7qqgxrIYEZ+ZmrfgvCmsuZIqz67/IuRtaXTzr0COKD/uv9KRHIx+xHsQ== + +"@flydotio/litestream-linux-arm64@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@flydotio/litestream-linux-arm64/-/litestream-linux-arm64-1.0.1.tgz#2f28ba86679bee59f206181865be89dda35ddc6a" + integrity sha512-/kukXjY+8xnAVUY3ywZIHIrW2gmKg5dXFVmSR/IQtdEwWZrKqdJ77fbK4u9bkacZqf94xn9jej8Cr4sToy6gNg== + +"@flydotio/litestream-linux-x64@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@flydotio/litestream-linux-x64/-/litestream-linux-x64-1.0.1.tgz#68acc68bf74841e778b1841cda5d113ba7a9248e" + integrity sha512-zmcAR8q2TNiAsWRSWscrN+r4NNQ+FwfatKhcE3G/YticNSkNyIhtCTlvXxIyOG+E+UWa+j441cjbmb7p83JPEw== + +"@flydotio/litestream@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@flydotio/litestream/-/litestream-1.0.1.tgz#82290d18433d1101d6333e7f271bf3490a39cb9c" + integrity sha512-hGIR37D1o8+AKcHa0PmdOG7dPm1RQsFQE3cqgt2udQVo3Q0NI5ruarLeaFWTFB6l+hjs97Xdlt0TgEufxLTzaQ== + optionalDependencies: + "@flydotio/litestream-darwin-arm64" "1.0.1" + "@flydotio/litestream-darwin-x64" "1.0.1" + "@flydotio/litestream-linux-arm64" "1.0.1" + "@flydotio/litestream-linux-x64" "1.0.1" + +"@inquirer/ansi@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@inquirer/ansi/-/ansi-1.0.2.tgz#674a4c4d81ad460695cb2a1fc69d78cd187f337e" + integrity sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ== + +"@inquirer/checkbox@^4.3.2": + version "4.3.2" + resolved "https://registry.yarnpkg.com/@inquirer/checkbox/-/checkbox-4.3.2.tgz#e1483e6519d6ffef97281a54d2a5baa0d81b3f3b" + integrity sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA== + dependencies: + "@inquirer/ansi" "^1.0.2" + "@inquirer/core" "^10.3.2" + "@inquirer/figures" "^1.0.15" + "@inquirer/type" "^3.0.10" + yoctocolors-cjs "^2.1.3" + +"@inquirer/confirm@^5.1.21": + version "5.1.21" + resolved "https://registry.yarnpkg.com/@inquirer/confirm/-/confirm-5.1.21.tgz#610c4acd7797d94890a6e2dde2c98eb1e891dd12" + integrity sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ== + dependencies: + "@inquirer/core" "^10.3.2" + "@inquirer/type" "^3.0.10" + +"@inquirer/core@^10.3.2": + version "10.3.2" + resolved "https://registry.yarnpkg.com/@inquirer/core/-/core-10.3.2.tgz#535979ff3ff4fe1e7cc4f83e2320504c743b7e20" + integrity sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A== + dependencies: + "@inquirer/ansi" "^1.0.2" + "@inquirer/figures" "^1.0.15" + "@inquirer/type" "^3.0.10" + cli-width "^4.1.0" + mute-stream "^2.0.0" + signal-exit "^4.1.0" + wrap-ansi "^6.2.0" + yoctocolors-cjs "^2.1.3" + +"@inquirer/editor@^4.2.23": + version "4.2.23" + resolved "https://registry.yarnpkg.com/@inquirer/editor/-/editor-4.2.23.tgz#fe046a3bfdae931262de98c1052437d794322e0b" + integrity sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ== + dependencies: + "@inquirer/core" "^10.3.2" + "@inquirer/external-editor" "^1.0.3" + "@inquirer/type" "^3.0.10" + +"@inquirer/expand@^4.0.23": + version "4.0.23" + resolved "https://registry.yarnpkg.com/@inquirer/expand/-/expand-4.0.23.tgz#a38b5f32226d75717c370bdfed792313b92bdc05" + integrity sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew== + dependencies: + "@inquirer/core" "^10.3.2" + "@inquirer/type" "^3.0.10" + yoctocolors-cjs "^2.1.3" + +"@inquirer/external-editor@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@inquirer/external-editor/-/external-editor-1.0.3.tgz#c23988291ee676290fdab3fd306e64010a6d13b8" + integrity sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA== + dependencies: + chardet "^2.1.1" + iconv-lite "^0.7.0" + +"@inquirer/figures@^1.0.15": + version "1.0.15" + resolved "https://registry.yarnpkg.com/@inquirer/figures/-/figures-1.0.15.tgz#dbb49ed80df11df74268023b496ac5d9acd22b3a" + integrity sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g== + +"@inquirer/input@^4.3.1": + version "4.3.1" + resolved "https://registry.yarnpkg.com/@inquirer/input/-/input-4.3.1.tgz#778683b4c4c4d95d05d4b05c4a854964b73565b4" + integrity sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g== + dependencies: + "@inquirer/core" "^10.3.2" + "@inquirer/type" "^3.0.10" + +"@inquirer/number@^3.0.23": + version "3.0.23" + resolved "https://registry.yarnpkg.com/@inquirer/number/-/number-3.0.23.tgz#3fdec2540d642093fd7526818fd8d4bdc7335094" + integrity sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg== + dependencies: + "@inquirer/core" "^10.3.2" + "@inquirer/type" "^3.0.10" + +"@inquirer/password@^4.0.23": + version "4.0.23" + resolved "https://registry.yarnpkg.com/@inquirer/password/-/password-4.0.23.tgz#b9f5187c8c92fd7aa9eceb9d8f2ead0d7e7b000d" + integrity sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA== + dependencies: + "@inquirer/ansi" "^1.0.2" + "@inquirer/core" "^10.3.2" + "@inquirer/type" "^3.0.10" + +"@inquirer/prompts@^7.10.1": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@inquirer/prompts/-/prompts-7.10.1.tgz#e1436c0484cf04c22548c74e2cd239e989d5f847" + integrity sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg== + dependencies: + "@inquirer/checkbox" "^4.3.2" + "@inquirer/confirm" "^5.1.21" + "@inquirer/editor" "^4.2.23" + "@inquirer/expand" "^4.0.23" + "@inquirer/input" "^4.3.1" + "@inquirer/number" "^3.0.23" + "@inquirer/password" "^4.0.23" + "@inquirer/rawlist" "^4.1.11" + "@inquirer/search" "^3.2.2" + "@inquirer/select" "^4.4.2" + +"@inquirer/rawlist@^4.1.11": + version "4.1.11" + resolved "https://registry.yarnpkg.com/@inquirer/rawlist/-/rawlist-4.1.11.tgz#313c8c3ffccb7d41e990c606465726b4a898a033" + integrity sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw== + dependencies: + "@inquirer/core" "^10.3.2" + "@inquirer/type" "^3.0.10" + yoctocolors-cjs "^2.1.3" + +"@inquirer/search@^3.2.2": + version "3.2.2" + resolved "https://registry.yarnpkg.com/@inquirer/search/-/search-3.2.2.tgz#4cc6fd574dcd434e4399badc37c742c3fd534ac8" + integrity sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA== + dependencies: + "@inquirer/core" "^10.3.2" + "@inquirer/figures" "^1.0.15" + "@inquirer/type" "^3.0.10" + yoctocolors-cjs "^2.1.3" + +"@inquirer/select@^4.4.2": + version "4.4.2" + resolved "https://registry.yarnpkg.com/@inquirer/select/-/select-4.4.2.tgz#2ac8fca960913f18f1d1b35323ed8fcd27d89323" + integrity sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w== + dependencies: + "@inquirer/ansi" "^1.0.2" + "@inquirer/core" "^10.3.2" + "@inquirer/figures" "^1.0.15" + "@inquirer/type" "^3.0.10" + yoctocolors-cjs "^2.1.3" + +"@inquirer/type@^3.0.10": + version "3.0.10" + resolved "https://registry.yarnpkg.com/@inquirer/type/-/type-3.0.10.tgz#11ed564ec78432a200ea2601a212d24af8150d50" + integrity sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA== + "@jridgewell/resolve-uri@^3.0.3": version "3.1.2" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" @@ -1174,7 +1361,12 @@ ajv@^8.0.0, ajv@^8.12.0: json-schema-traverse "^1.0.0" require-from-string "^2.0.2" -ansi-styles@^4.1.0: +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== @@ -1200,6 +1392,11 @@ assertion-error@^2.0.1: resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-2.0.1.tgz#f641a196b335690b1070bf00b6e7593fec190bf7" integrity sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA== +async@^3.2.6: + version "3.2.6" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.6.tgz#1b0728e14929d51b85b449b7f06e27c1145e38ce" + integrity sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA== + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -1227,6 +1424,11 @@ axios@^1.6.8: form-data "^4.0.0" proxy-from-env "^1.1.0" +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + base64-js@^1.3.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" @@ -1252,6 +1454,13 @@ bottleneck@^2.15.3: resolved "https://registry.yarnpkg.com/bottleneck/-/bottleneck-2.19.5.tgz#5df0b90f59fd47656ebe63c78a98419205cadd91" integrity sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw== +brace-expansion@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.2.tgz#54fc53237a613d854c7bd37463aad17df87214e7" + integrity sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ== + dependencies: + balanced-match "^1.0.0" + buffer-equal-constant-time@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" @@ -1310,11 +1519,35 @@ chalk@4.1.2: ansi-styles "^4.1.0" supports-color "^7.1.0" +chalk@^5.4.1: + version "5.6.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.6.2.tgz#b1238b6e23ea337af71c7f8a295db5af0c158aea" + integrity sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA== + +chardet@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-2.1.1.tgz#5c75593704a642f71ee53717df234031e65373c8" + integrity sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ== + check-error@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/check-error/-/check-error-2.1.1.tgz#87eb876ae71ee388fa0471fe423f494be1d96ccc" integrity sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw== +cli-width@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-4.1.0.tgz#42daac41d3c254ef38ad8ac037672130173691c5" + integrity sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ== + +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" + color-convert@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" @@ -1436,6 +1669,11 @@ diff@^4.0.1: resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== +diff@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-7.0.0.tgz#3fb34d387cd76d803f6eebea67b921dab0182a9a" + integrity sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw== + dotenv-cli@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/dotenv-cli/-/dotenv-cli-8.0.0.tgz#cea1519f5a06c7372a1428fca4605fcf3d50e1cf" @@ -1477,6 +1715,13 @@ ecdsa-sig-formatter@1.0.11: dependencies: safe-buffer "^5.0.1" +ejs@^3.1.10: + version "3.1.10" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.10.tgz#69ab8358b14e896f80cc39e62087b88500c3ac3b" + integrity sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA== + dependencies: + jake "^10.8.5" + elevenlabs@^1.54.0: version "1.54.0" resolved "https://registry.yarnpkg.com/elevenlabs/-/elevenlabs-1.54.0.tgz#195899e367ff2b9f000c0f4e577a21fedf1f6a3a" @@ -1492,6 +1737,11 @@ elevenlabs@^1.54.0: readable-stream "^4.5.2" url-join "4.0.1" +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + end-of-stream@^1.1.0: version "1.4.5" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.5.tgz#7344d711dea40e0b74abc2ed49778743ccedb08c" @@ -1602,6 +1852,11 @@ esbuild@~0.23.0: "@esbuild/win32-ia32" "0.23.1" "@esbuild/win32-x64" "0.23.1" +escalade@^3.1.1: + version "3.2.0" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== + estree-walker@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-3.0.3.tgz#67c3e549ec402a487b4fc193d1953a524752340d" @@ -1739,6 +1994,13 @@ fdir@^6.4.4: resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.4.5.tgz#328e280f3a23699362f95f2e82acf978a0c0cb49" integrity sha512-4BG7puHpVsIYxZUbiUE3RqGloLaSSwzYie5jvasC4LWuBWzZawynvYouhjbQKw2JuIGYdm0DzIxl8iVidKlUEw== +filelist@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" + integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== + dependencies: + minimatch "^5.0.1" + find-my-way@^9.0.0: version "9.2.0" resolved "https://registry.yarnpkg.com/find-my-way/-/find-my-way-9.2.0.tgz#6f845aac6227adcb683134f60bd9e8c144af21da" @@ -1782,6 +2044,11 @@ function-bind@^1.1.2: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + get-intrinsic@^1.2.5, get-intrinsic@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01" @@ -1855,16 +2122,41 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== +iconv-lite@^0.7.0: + version "0.7.2" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.7.2.tgz#d0bdeac3f12b4835b7359c2ad89c422a4d1cc72e" + integrity sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + ieee754@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== +inquirer@^12.4.1: + version "12.11.1" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-12.11.1.tgz#3f5770b9ec926b0909e463e42c766f2664f2cc96" + integrity sha512-9VF7mrY+3OmsAfjH3yKz/pLbJ5z22E23hENKw3/LNSaA/sAt3v49bDRY+Ygct1xwuKT+U+cBfTzjCPySna69Qw== + dependencies: + "@inquirer/ansi" "^1.0.2" + "@inquirer/core" "^10.3.2" + "@inquirer/prompts" "^7.10.1" + "@inquirer/type" "^3.0.10" + mute-stream "^2.0.0" + run-async "^4.0.6" + rxjs "^7.8.2" + ipaddr.js@^2.1.0: version "2.2.0" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.2.0.tgz#d33fa7bac284f4de7af949638c9d68157c6b92e8" integrity sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA== +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + is-stream@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" @@ -1875,6 +2167,15 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== +jake@^10.8.5: + version "10.9.4" + resolved "https://registry.yarnpkg.com/jake/-/jake-10.9.4.tgz#d626da108c63d5cfb00ab5c25fadc7e0084af8e6" + integrity sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA== + dependencies: + async "^3.2.6" + filelist "^1.0.4" + picocolors "^1.1.1" + jiti@2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/jiti/-/jiti-2.4.2.tgz#d19b7732ebb6116b06e2038da74a55366faef560" @@ -2030,6 +2331,13 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +minimatch@^5.0.1: + version "5.1.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== + dependencies: + brace-expansion "^2.0.1" + minimist@^1.2.6: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" @@ -2052,6 +2360,11 @@ ms@^2.1.1, ms@^2.1.3: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +mute-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-2.0.0.tgz#a5446fc0c512b71c83c44d908d5c7b7b4c493b2b" + integrity sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA== + nanoid@^3.3.11: version "3.3.11" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b" @@ -2318,6 +2631,11 @@ reflect-metadata@^0.2.2: resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.2.2.tgz#400c845b6cba87a21f2c65c4aeb158f4fa4d9c5b" integrity sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q== +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + require-from-string@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" @@ -2372,6 +2690,18 @@ rollup@^4.34.9: "@rollup/rollup-win32-x64-msvc" "4.41.1" fsevents "~2.3.2" +run-async@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-4.0.6.tgz#d53b86acb71f42650fe23de2b3c1b6b6b34b9294" + integrity sha512-IoDlSLTs3Yq593mb3ZoKWKXMNu3UpObxhgA/Xuid5p4bbfi2jdY1Hj0m1K+0/tEuQTxIGMhQDqGjKb7RuxGpAQ== + +rxjs@^7.8.2: + version "7.8.2" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.2.tgz#955bc473ed8af11a002a2be52071bf475638607b" + integrity sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA== + dependencies: + tslib "^2.1.0" + safe-buffer@^5.0.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" @@ -2389,6 +2719,11 @@ safe-stable-stringify@^2.3.1: resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz#4ca2f8e385f2831c432a719b108a3bf7af42a1dd" integrity sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA== +"safer-buffer@>= 2.1.2 < 3.0.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + secure-json-parse@^2.4.0: version "2.7.0" resolved "https://registry.yarnpkg.com/secure-json-parse/-/secure-json-parse-2.7.0.tgz#5a5f9cd6ae47df23dba3151edd06855d47e09862" @@ -2428,6 +2763,11 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== +shell-quote@^1.8.2: + version "1.8.3" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.3.tgz#55e40ef33cf5c689902353a3d8cd1a6725f08b4b" + integrity sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw== + side-channel-list@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/side-channel-list/-/side-channel-list-1.0.0.tgz#10cb5984263115d3b7a0e336591e290a830af8ad" @@ -2478,6 +2818,11 @@ signal-exit@^3.0.3: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== +signal-exit@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + socket.io-adapter@^2.5.5, socket.io-adapter@~2.5.2: version "2.5.5" resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz#c7a1f9c703d7756844751b6ff9abfc1780664082" @@ -2534,6 +2879,15 @@ std-env@^3.9.0: resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.9.0.tgz#1a6f7243b339dca4c9fd55e1c7504c77ef23e8f1" integrity sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw== +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + string_decoder@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" @@ -2541,6 +2895,13 @@ string_decoder@^1.3.0: dependencies: safe-buffer "~5.2.0" +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-final-newline@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" @@ -2649,7 +3010,7 @@ tslib@^1.9.3: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.7.0, tslib@^2.8.1: +tslib@^2.1.0, tslib@^2.7.0, tslib@^2.8.1: version "2.8.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== @@ -2812,6 +3173,24 @@ why-is-node-running@^2.3.0: siginfo "^2.0.0" stackback "0.0.2" +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -2822,6 +3201,11 @@ ws@~8.17.1: resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b" integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ== +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" @@ -2832,11 +3216,34 @@ yaml@^2.4.2: resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.4.2.tgz#7a2b30f2243a5fc299e1f14ca58d475ed4bc5362" integrity sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA== +yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + +yargs@^17.7.2: + version "17.7.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== + dependencies: + cliui "^8.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.1.1" + yn@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== +yoctocolors-cjs@^2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz#7e4964ea8ec422b7a40ac917d3a344cfd2304baa" + integrity sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw== + zod-to-json-schema@^3.23.3, zod-to-json-schema@^3.24.3: version "3.24.3" resolved "https://registry.yarnpkg.com/zod-to-json-schema/-/zod-to-json-schema-3.24.3.tgz#5958ba111d681f8d01c5b6b647425c9b8a6059e7"