diff --git a/.gitmodules b/.gitmodules index e24bb0c..222a086 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "drop-base"] path = drop-base - url = https://github.com/Drop-OSS/drop-base.git + url = https://github.com/Drop-OSS/drop-base.git \ No newline at end of file diff --git a/nuxt.config.ts b/nuxt.config.ts index e4e014d..b5aac82 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -2,6 +2,17 @@ import tailwindcss from "@tailwindcss/vite"; // https://nuxt.com/docs/api/configuration/nuxt-config export default defineNuxtConfig({ + extends: ["./drop-base"], + + // Module config from here down + modules: [ + "vue3-carousel-nuxt", + "nuxt-security", + // "@nuxt/image", + "@nuxt/fonts", + "@nuxt/eslint", + ], + // Nuxt-only config telemetry: false, compatibilityDate: "2024-04-03", @@ -21,6 +32,10 @@ export default defineNuxtConfig({ viewTransition: true, }, + // future: { + // compatibilityVersion: 4, + // }, + vite: { plugins: [tailwindcss()], }, @@ -76,17 +91,6 @@ export default defineNuxtConfig({ }, }, - extends: ["./drop-base"], - - // Module config from here down - modules: [ - "vue3-carousel-nuxt", - "nuxt-security", - // "@nuxt/image", - "@nuxt/fonts", - "@nuxt/eslint", - ], - carousel: { prefix: "Vue", }, diff --git a/package.json b/package.json index 14c2030..699d1d2 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ }, "dependencies": { "@drop-oss/droplet": "^0.7.2", + "@drop-oss/headscalez": "0.0.4", "@headlessui/vue": "^1.7.23", "@heroicons/vue": "^2.1.5", "@nuxt/fonts": "^0.11.0", @@ -56,7 +57,8 @@ "@types/turndown": "^5.0.5", "autoprefixer": "^10.4.20", "eslint": "^9.24.0", - "eslint-config-prettier": "^10.1.1", + "eslint-config-prettier": "^10.1.5", + "eslint-plugin-prettier": "^5.4.0", "h3": "^1.15.1", "ofetch": "^1.4.1", "postcss": "^8.4.47", diff --git a/server/api/v1/client/peer/index.get.ts b/server/api/v1/client/peer/index.get.ts new file mode 100644 index 0000000..c37d8cd --- /dev/null +++ b/server/api/v1/client/peer/index.get.ts @@ -0,0 +1,20 @@ +import { ClientCapabilities } from "~/prisma/client"; +import { defineClientEventHandler } from "~/server/internal/clients/event-handler"; +import headscaleManager from "~/server/internal/p2p/headscale"; + +export default defineClientEventHandler(async (h3, { fetchClient }) => { + const client = await fetchClient(); + if (!client.capabilities.includes(ClientCapabilities.PeerAPI)) + throw createError({ + statusCode: 403, + statusMessage: "Capability not allowed.", + }); + + if (!headscaleManager.enabled()) + throw createError({ + statusCode: 500, + statusMessage: "Peer network not available.", + }); + + return headscaleManager.configuration(); +}); diff --git a/server/api/v1/client/peer/index.post.ts b/server/api/v1/client/peer/index.post.ts new file mode 100644 index 0000000..775a7f4 --- /dev/null +++ b/server/api/v1/client/peer/index.post.ts @@ -0,0 +1,26 @@ +import { ClientCapabilities } from "~/prisma/client"; +import { defineClientEventHandler } from "~/server/internal/clients/event-handler"; +import headscaleManager from "~/server/internal/p2p/headscale"; + +export default defineClientEventHandler( + async (h3, { fetchClient, fetchUser }) => { + const client = await fetchClient(); + if (!client.capabilities.includes(ClientCapabilities.PeerAPI)) + throw createError({ + statusCode: 403, + statusMessage: "Capability not allowed.", + }); + + if (!headscaleManager.enabled()) + throw createError({ + statusCode: 500, + statusMessage: "Peer network not available.", + }); + + const user = await fetchUser(); + + const key = await headscaleManager.createPreauthKey(user, client); + + return key; + }, +); diff --git a/server/internal/clients/ca-store.ts b/server/internal/clients/ca-store.ts index 317515b..a424731 100644 --- a/server/internal/clients/ca-store.ts +++ b/server/internal/clients/ca-store.ts @@ -2,6 +2,7 @@ import path from "path"; import fs from "fs"; import type { CertificateBundle } from "./ca"; import prisma from "../db/database"; +import { systemConfig } from "../config/sys-conf"; export type CertificateStore = { store(name: string, data: CertificateBundle): Promise; @@ -10,7 +11,8 @@ export type CertificateStore = { checkBlacklistCertificate(name: string): Promise; }; -export const fsCertificateStore = (base: string) => { +export const fsCertificateStore = () => { + const base = path.join(systemConfig.getDataFolder(), "certs"); const blacklist = path.join(base, ".blacklist"); fs.mkdirSync(blacklist, { recursive: true }); const store: CertificateStore = { diff --git a/server/internal/config/sys-conf.ts b/server/internal/config/sys-conf.ts new file mode 100644 index 0000000..0d0b5e2 --- /dev/null +++ b/server/internal/config/sys-conf.ts @@ -0,0 +1,21 @@ +import path from "path"; + +class SystemConfig { + private libraryFolder = process.env.LIBRARY ?? "./.data/library"; + private dataFolder = process.env.DATA ?? "./.data/data"; + private headscaleFolder = path.join(this.dataFolder, "headscale"); + + getLibraryFolder() { + return this.libraryFolder; + } + + getDataFolder() { + return this.dataFolder; + } + + getHeadscaleFolder() { + return this.headscaleFolder; + } +} + +export const systemConfig = new SystemConfig(); diff --git a/server/internal/library/index.ts b/server/internal/library/index.ts index 91d3b21..6556702 100644 --- a/server/internal/library/index.ts +++ b/server/internal/library/index.ts @@ -15,12 +15,13 @@ import taskHandler from "../tasks"; import { parsePlatform } from "../utils/parseplatform"; import droplet from "@drop-oss/droplet"; import notificationSystem from "../notifications"; +import { systemConfig } from "../config/sys-conf"; class LibraryManager { private basePath: string; constructor() { - this.basePath = process.env.LIBRARY ?? "./.data/library"; + this.basePath = systemConfig.getLibraryFolder(); fs.mkdirSync(this.basePath, { recursive: true }); } diff --git a/server/internal/objects/fsBackend.ts b/server/internal/objects/fsBackend.ts index 3f0b865..34e0800 100644 --- a/server/internal/objects/fsBackend.ts +++ b/server/internal/objects/fsBackend.ts @@ -7,6 +7,7 @@ import { Readable } from "stream"; import { createHash } from "crypto"; import prisma from "../db/database"; import cacheHandler from "../cache"; +import { systemConfig } from "../config/sys-conf"; export class FsObjectBackend extends ObjectBackend { private baseObjectPath: string; @@ -16,7 +17,7 @@ export class FsObjectBackend extends ObjectBackend { constructor() { super(); - const basePath = process.env.FS_BACKEND_PATH ?? "./.data/objects"; + const basePath = path.join(systemConfig.getDataFolder(), "objects"); this.baseObjectPath = path.join(basePath, "objects"); this.baseMetadataPath = path.join(basePath, "metadata"); diff --git a/server/internal/p2p/headscale.ts b/server/internal/p2p/headscale.ts new file mode 100644 index 0000000..2472334 --- /dev/null +++ b/server/internal/p2p/headscale.ts @@ -0,0 +1,82 @@ +import type { HeadscaleService } from "@drop-oss/headscalez"; +import { HeadscaleControlService, startHeadscale } from "@drop-oss/headscalez"; +import { systemConfig } from "../config/sys-conf"; +import type { Client, User } from "~/prisma/client"; + +export class HeadscaleManager { + private controlURL?: string; + private headscaleService?: HeadscaleService; + private headscaleClient?: HeadscaleControlService; + + constructor() { + this.setup(); + } + + async setup() { + const externalUrl = process.env.CONTROL_URL; + if (externalUrl) { + this.controlURL = externalUrl; + const headscale = await startHeadscale({ + externalUrl, + dir: systemConfig.getHeadscaleFolder(), + }); + this.headscaleService = headscale; + this.headscaleClient = new HeadscaleControlService(headscale); + } + } + + enabled() { + return !!this.headscaleService; + } + + configuration() { + if (!this.controlURL) throw new Error("Headscale not available"); + return { + controlURL: this.controlURL, + }; + } + + private async fetchUser(user: User) { + if (!this.headscaleClient) + throw new Error("Headscale client not available"); + const { response } = await this.headscaleClient.client.listUsers({ + id: 0n, + name: user.id, + email: "", + }); + + if (response.users.length == 0) { + const { response } = await this.headscaleClient.client.createUser({ + name: user.id, + displayName: user.displayName, + email: user.email, + pictureUrl: user.profilePictureObjectId, + }); + + if (!response.user) throw new Error("Could not create user"); + + return response.user; + } + + return response.users[0]; + } + + async createPreauthKey(user: User, client: Client) { + if (!this.headscaleClient) + throw new Error("Headscale client not available"); + + const headscaleUser = await this.fetchUser(user); + const { response } = await this.headscaleClient.client.createPreAuthKey({ + user: headscaleUser.name, + reusable: false, + ephemeral: false, + aclTags: ["client", `user:${user.id}`, `client:${client.id}`], + }); + + if (!response.preAuthKey) throw new Error("Could not create pre-auth key"); + return response.preAuthKey; + } +} + +export const headscaleManager = new HeadscaleManager(); +export default headscaleManager; diff --git a/server/plugins/ca.ts b/server/plugins/ca.ts index 0650f51..4f2aff2 100644 --- a/server/plugins/ca.ts +++ b/server/plugins/ca.ts @@ -9,9 +9,7 @@ export const useCertificateAuthority = () => { }; export default defineNitroPlugin(async () => { - // const basePath = process.env.CLIENT_CERTIFICATES ?? "./certs"; - // fs.mkdirSync(basePath, { recursive: true }); - // const store = fsCertificateStore(basePath); + // const store = fsCertificateStore(); ca = await CertificateAuthority.new(dbCertificateStore()); }); diff --git a/yarn.lock b/yarn.lock index 73d1c63..68fcd2c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -371,6 +371,19 @@ "@drop-oss/droplet-win32-arm64-msvc" "0.7.2" "@drop-oss/droplet-win32-x64-msvc" "0.7.2" +"@drop-oss/headscalez@0.0.4": + version "0.0.4" + resolved "https://registry.yarnpkg.com/@drop-oss/headscalez/-/headscalez-0.0.4.tgz#7558fbbc542d93fb0c69bdcf48917bdae676c62d" + integrity sha512-vdDq6Qe/T5S0FKKYdnBXvOh53wGs8nxy6O3ACVyUjTbTGkDn3z5og4joh5TxoAOFodPHRLCihVuroiymS7yNTg== + dependencies: + "@protobuf-ts/grpcweb-transport" "^2.10.0" + "@protobuf-ts/runtime" "^2.10.0" + "@protobuf-ts/runtime-rpc" "^2.10.0" + execa "^9.5.3" + fs-extra "^11.3.0" + node-graceful-shutdown "^1.1.5" + ofetch "^1.4.1" + "@emnapi/core@^1.4.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@emnapi/core/-/core-1.4.0.tgz#8844b02d799198158ac1fea21ae2bc81b881da9a" @@ -1459,6 +1472,11 @@ resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.2.1.tgz#6d083acfddae21fb329c8df8c94bf895ce7d0c15" integrity sha512-VzgHzGblFmUeBmmrk55zPyrQIArQN4vujc9shWytaPdB3P7qhi0cpaiKIr7tlCmFv2lYUwnLospIqjL9ZSAhhg== +"@pkgr/core@^0.2.3": + version "0.2.4" + resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.2.4.tgz#d897170a2b0ba51f78a099edccd968f7b103387c" + integrity sha512-ROFF39F6ZrnzSUEmQQZUar0Jt4xVoP9WnDRdWwF4NNcXs3xBTLgBUDoOwW141y1jP+S8nahIbdxbFC7IShw9Iw== + "@polka/url@^1.0.0-next.24": version "1.0.0-next.28" resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.28.tgz#d45e01c4a56f143ee69c54dd6b12eade9e270a73" @@ -1534,6 +1552,26 @@ dependencies: "@prisma/debug" "6.7.0" +"@protobuf-ts/grpcweb-transport@^2.10.0": + version "2.10.0" + resolved "https://registry.yarnpkg.com/@protobuf-ts/grpcweb-transport/-/grpcweb-transport-2.10.0.tgz#c09f29694ec7dc4fc1107a0bf30d359325939311" + integrity sha512-VUyD+8kn4XEfWoEiKjAsWX5XWkt8Gfdp/uquS17yt9hdfMBVx3o5tlXX5ylwfWhcIjbRvkf7WHEEdS2wMuq86Q== + dependencies: + "@protobuf-ts/runtime" "^2.10.0" + "@protobuf-ts/runtime-rpc" "^2.10.0" + +"@protobuf-ts/runtime-rpc@^2.10.0": + version "2.10.0" + resolved "https://registry.yarnpkg.com/@protobuf-ts/runtime-rpc/-/runtime-rpc-2.10.0.tgz#68de8dcc369e56579569a4deafd394cf4683dc66" + integrity sha512-8CS/XPv3+pMK4v8UKhtCdvbS4h9l7aqlteKdRt0/UbIKZ8n0qHj6hX8cBhz2ngvohxCOS0N08zPr9aCLBNhW3Q== + dependencies: + "@protobuf-ts/runtime" "^2.10.0" + +"@protobuf-ts/runtime@^2.10.0": + version "2.10.0" + resolved "https://registry.yarnpkg.com/@protobuf-ts/runtime/-/runtime-2.10.0.tgz#bc90f632647ff2ae72887546ddf3d193f3f43d98" + integrity sha512-ypYwGg9Pn3W/2lZ7/HW60hONGuSdzphvOY8Dq7LeNttymDe0y3LaTUUMRpuGqOT6FfrWEMnfQbyqU8AAreo8wA== + "@rollup/plugin-alias@^5.1.1": version "5.1.1" resolved "https://registry.yarnpkg.com/@rollup/plugin-alias/-/plugin-alias-5.1.1.tgz#53601d88cda8b1577aa130b4a6e452283605bf26" @@ -1705,6 +1743,11 @@ resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.38.0.tgz#38197da22c1af7b6b5d1cc7541757379193b8e83" integrity sha512-jjqy3uWlecfB98Psxb5cD6Fny9Fupv9LrDSPTQZUROqjvZmcCqNu4UMl7qqhlUUGpwiAkotj6GYu4SZdcr/nLw== +"@sec-ant/readable-stream@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz#60de891bb126abfdc5410fdc6166aca065f10a0c" + integrity sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg== + "@sindresorhus/is@^7.0.1": version "7.0.1" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-7.0.1.tgz#693cd0bfa7fdc71a3386b72088b660fb70851927" @@ -1715,6 +1758,11 @@ resolved "https://registry.yarnpkg.com/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz#719df7fb41766bc143369eaa0dd56d8dc87c9958" integrity sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg== +"@sindresorhus/merge-streams@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz#abb11d99aeb6d27f1b563c38147a72d50058e339" + integrity sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ== + "@speed-highlight/core@^1.2.7": version "1.2.7" resolved "https://registry.yarnpkg.com/@speed-highlight/core/-/core-1.2.7.tgz#eeaa7c1e7198559abbb98e4acbc93d108d35f2d3" @@ -3546,10 +3594,10 @@ eslint-config-flat-gitignore@^2.1.0: dependencies: "@eslint/compat" "^1.2.5" -eslint-config-prettier@^10.1.1: - version "10.1.1" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-10.1.1.tgz#cf0ff6e5c4e7e15f129f1f1ce2a5ecba92dec132" - integrity sha512-4EQQr6wXwS+ZJSzaR5ZCrYgLxqvUjdXctaEtBqHcbkW944B1NQyO4qpdHQbXBONfwxXdkAY81HH4+LUfrg+zPw== +eslint-config-prettier@^10.1.5: + version "10.1.5" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-10.1.5.tgz#00c18d7225043b6fbce6a665697377998d453782" + integrity sha512-zc1UmCpNltmVY34vuLRV61r1K27sWuX39E+uyUnY8xS2Bex88VV9cugG+UZbRSRGtGyFboj+D8JODyme1plMpw== eslint-flat-config-utils@^2.0.1: version "2.0.1" @@ -3608,6 +3656,14 @@ eslint-plugin-jsdoc@^50.6.9: spdx-expression-parse "^4.0.0" synckit "^0.9.1" +eslint-plugin-prettier@^5.4.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.4.0.tgz#54d4748904e58eaf1ffe26c4bffa4986ca7f952b" + integrity sha512-BvQOvUhkVQM1i63iMETK9Hjud9QhqBnbtT1Zc642p9ynzBuCe5pybkOnvqZIBypXmMlsGcnU4HZ8sCTPfpAexA== + dependencies: + prettier-linter-helpers "^1.0.0" + synckit "^0.11.0" + eslint-plugin-regexp@^2.7.0: version "2.7.0" resolved "https://registry.yarnpkg.com/eslint-plugin-regexp/-/eslint-plugin-regexp-2.7.0.tgz#84fa2d2b122e343f596cfb83ed8a5517a1dfef2a" @@ -3803,6 +3859,24 @@ execa@^8.0.1: signal-exit "^4.1.0" strip-final-newline "^3.0.0" +execa@^9.5.3: + version "9.5.3" + resolved "https://registry.yarnpkg.com/execa/-/execa-9.5.3.tgz#aa9b6e92ea6692b88a240efc260ca30489b33e2a" + integrity sha512-QFNnTvU3UjgWFy8Ef9iDHvIdcgZ344ebkwYx4/KLbR+CKQA4xBaHzv+iRpp86QfMHP8faFQLh8iOc57215y4Rg== + dependencies: + "@sindresorhus/merge-streams" "^4.0.0" + cross-spawn "^7.0.3" + figures "^6.1.0" + get-stream "^9.0.0" + human-signals "^8.0.0" + is-plain-obj "^4.1.0" + is-stream "^4.0.1" + npm-run-path "^6.0.0" + pretty-ms "^9.0.0" + signal-exit "^4.1.0" + strip-final-newline "^4.0.0" + yoctocolors "^2.0.0" + expand-template@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" @@ -3828,6 +3902,11 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== +fast-diff@^1.1.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" + integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== + fast-fifo@^1.2.0, fast-fifo@^1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/fast-fifo/-/fast-fifo-1.3.2.tgz#286e31de96eb96d38a97899815740ba2a4f3640c" @@ -3878,6 +3957,13 @@ fdir@^6.2.0, fdir@^6.4.3: resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.4.3.tgz#011cdacf837eca9b811c89dbb902df714273db72" integrity sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw== +figures@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-6.1.0.tgz#935479f51865fa7479f6fa94fc6fc7ac14e62c4a" + integrity sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg== + dependencies: + is-unicode-supported "^2.0.0" + file-entry-cache@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-8.0.0.tgz#7787bddcf1131bffb92636c69457bbc0edd6d81f" @@ -4012,6 +4098,15 @@ fs-constants@^1.0.0: resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== +fs-extra@^11.3.0: + version "11.3.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.3.0.tgz#0daced136bbaf65a555a326719af931adc7a314d" + integrity sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + fsevents@2.3.3, fsevents@~2.3.2, fsevents@~2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" @@ -4071,6 +4166,14 @@ get-stream@^8.0.1: resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-8.0.1.tgz#def9dfd71742cd7754a7761ed43749a27d02eca2" integrity sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA== +get-stream@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-9.0.1.tgz#95157d21df8eb90d1647102b63039b1df60ebd27" + integrity sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA== + dependencies: + "@sec-ant/readable-stream" "^0.4.1" + is-stream "^4.0.1" + get-tsconfig@^4.10.0: version "4.10.0" resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.10.0.tgz#403a682b373a823612475a4c2928c7326fc0f6bb" @@ -4175,7 +4278,7 @@ gopd@^1.2.0: resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1" integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== -graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.9: +graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.9: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== @@ -4290,6 +4393,11 @@ human-signals@^5.0.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-5.0.0.tgz#42665a284f9ae0dade3ba41ebc37eb4b852f3a28" integrity sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ== +human-signals@^8.0.0: + version "8.0.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-8.0.1.tgz#f08bb593b6d1db353933d06156cedec90abe51fb" + integrity sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ== + ieee754@^1.1.13, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" @@ -4482,6 +4590,11 @@ is-path-inside@^4.0.0: resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-4.0.0.tgz#805aeb62c47c1b12fc3fd13bfb3ed1e7430071db" integrity sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA== +is-plain-obj@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz#d65025edec3657ce032fd7db63c97883eaed71f0" + integrity sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg== + is-reference@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7" @@ -4506,6 +4619,16 @@ is-stream@^3.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== +is-stream@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-4.0.1.tgz#375cf891e16d2e4baec250b85926cffc14720d9b" + integrity sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A== + +is-unicode-supported@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz#09f0ab0de6d3744d48d265ebb98f65d11f2a9b3a" + integrity sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ== + is-what@^4.1.8: version "4.1.16" resolved "https://registry.yarnpkg.com/is-what/-/is-what-4.1.16.tgz#1ad860a19da8b4895ad5495da3182ce2acdd7a6f" @@ -4633,6 +4756,15 @@ json5@^2.2.3: resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + keyv@^4.5.4: version "4.5.4" resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" @@ -5412,6 +5544,11 @@ node-forge@^1.3.1: resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== +node-graceful-shutdown@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/node-graceful-shutdown/-/node-graceful-shutdown-1.1.5.tgz#2c5b405a27d712a409e69b67dfe215d30154faff" + integrity sha512-tlz8XpPr+pqrEGWFNLtMwd0HdFsCAKp5NCmMvwcTZTA0hyrVd7gkKbivDcSM5uYB1331/cEjNTtmVtqKy8OSBw== + node-gyp-build@^4.2.2, node-gyp-build@^4.8.1: version "4.8.4" resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.4.tgz#8a70ee85464ae52327772a90d66c6077a900cfc8" @@ -5745,6 +5882,11 @@ parse-json@^8.0.0: index-to-position "^1.0.0" type-fest "^4.37.0" +parse-ms@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-4.0.0.tgz#c0c058edd47c2a590151a718990533fd62803df4" + integrity sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw== + parse-path@^7.0.0: version "7.0.1" resolved "https://registry.yarnpkg.com/parse-path/-/parse-path-7.0.1.tgz#ae548cd36315fd8881a3610eae99fa08123ee0e2" @@ -6126,6 +6268,13 @@ prelude-ls@^1.2.1: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + prettier@^3.5.3: version "3.5.3" resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.5.3.tgz#4fc2ce0d657e7a02e602549f053b239cb7dfe1b5" @@ -6136,6 +6285,13 @@ pretty-bytes@^6.1.1: resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-6.1.1.tgz#38cd6bb46f47afbf667c202cfc754bffd2016a3b" integrity sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ== +pretty-ms@^9.0.0: + version "9.2.0" + resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-9.2.0.tgz#e14c0aad6493b69ed63114442a84133d7e560ef0" + integrity sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg== + dependencies: + parse-ms "^4.0.0" + prisma@^6.7.0: version "6.7.0" resolved "https://registry.yarnpkg.com/prisma/-/prisma-6.7.0.tgz#7890e352bde11f6ec3018802d3fc1bcbe0027bd2" @@ -6842,6 +6998,11 @@ strip-final-newline@^3.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== +strip-final-newline@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-4.0.0.tgz#35a369ec2ac43df356e3edd5dcebb6429aa1fa5c" + integrity sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw== + strip-indent@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-4.0.0.tgz#b41379433dd06f5eae805e21d631e07ee670d853" @@ -6924,6 +7085,14 @@ svgo@^3.2.0, svgo@^3.3.2: csso "^5.0.5" picocolors "^1.0.0" +synckit@^0.11.0: + version "0.11.4" + resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.11.4.tgz#48972326b59723fc15b8d159803cf8302b545d59" + integrity sha512-Q/XQKRaJiLiFIBNN+mndW7S/RHxvwzuZS6ZwmRzUBqJBv/5QIKCEwkBC8GBf8EQJKYnaFs0wOZbKTXBPj8L9oQ== + dependencies: + "@pkgr/core" "^0.2.3" + tslib "^2.8.1" + synckit@^0.9.1: version "0.9.2" resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.9.2.tgz#a3a935eca7922d48b9e7d6c61822ee6c3ae4ec62" @@ -7240,6 +7409,11 @@ unimport@^4.1.2, unimport@^4.1.3: unplugin "^2.2.2" unplugin-utils "^0.2.4" +universalify@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" + integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== + unplugin-remove@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/unplugin-remove/-/unplugin-remove-1.0.3.tgz#daf24110c2a0f5f679bb72aed9418078b1008043" @@ -7706,6 +7880,11 @@ yocto-queue@^1.0.0: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.2.1.tgz#36d7c4739f775b3cbc28e6136e21aa057adec418" integrity sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg== +yoctocolors@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/yoctocolors/-/yoctocolors-2.1.1.tgz#e0167474e9fbb9e8b3ecca738deaa61dd12e56fc" + integrity sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ== + youch-core@^0.3.1, youch-core@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/youch-core/-/youch-core-0.3.2.tgz#b8d473857cceb06f9ef5a9fd6c1038c80f132570"