diff --git a/.editoconfig b/.editoconfig new file mode 100644 index 0000000..37d38bb --- /dev/null +++ b/.editoconfig @@ -0,0 +1,9 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 2 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index bd147bd..398d47c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,8 @@ -FROM denoland/deno:2.3.1 +FROM denoland/deno:2.5.1 + ENV TZ=UTC ENV PORT=8370 + EXPOSE 8370 WORKDIR /app @@ -10,10 +12,6 @@ COPY relay/ ./relay/ COPY .npmrc . COPY deno-docker.json ./deno.json -RUN chown -R deno:deno /app/ - -USER deno - RUN deno install --allow-scripts CMD ["sh", "-c", "deno run --allow-all ./api/.tasks/migrate.ts && deno run --allow-all ./api/server.ts"] \ No newline at end of file diff --git a/api/.bruno/account/GetById.bru b/api/.bruno/account/GetById.bru new file mode 100644 index 0000000..53c4253 --- /dev/null +++ b/api/.bruno/account/GetById.bru @@ -0,0 +1,19 @@ +meta { + name: Get By ID + type: http + seq: 2 +} + +get { + url: {{url}}/accounts/:id + body: none + auth: inherit +} + +params:path { + id: +} + +settings { + encodeUrl: true +} diff --git a/api/libraries/auth/access.ts b/api/libraries/auth/access.ts new file mode 100644 index 0000000..830897c --- /dev/null +++ b/api/libraries/auth/access.ts @@ -0,0 +1,19 @@ +import { cerbos } from "./cerbos.ts"; +import type { Principal } from "./principal.ts"; +import { Resource } from "./resources.ts"; + +export function access(principal: Principal) { + return { + isAllowed(resource: Resource, action: string) { + return cerbos.isAllowed({ principal, resource, action }); + }, + checkResource(resource: Resource, actions: string[]) { + return cerbos.checkResource({ principal, resource, actions }); + }, + checkResources(resources: { resource: Resource; actions: string[] }[]) { + return cerbos.checkResources({ principal, resources }); + }, + }; +} + +export type Access = ReturnType; diff --git a/api/libraries/auth/auth.ts b/api/libraries/auth/auth.ts index 74ecbfb..970946b 100644 --- a/api/libraries/auth/auth.ts +++ b/api/libraries/auth/auth.ts @@ -1,82 +1,21 @@ -import { Auth, ResolvedSession } from "@valkyr/auth"; -import z from "zod"; - -import { db } from "~stores/read-store/database.ts"; +import { Auth } from "@valkyr/auth"; +import { access } from "./access.ts"; import { config } from "./config.ts"; +import { principal } from "./principal.ts"; +import { resources } from "./resources.ts"; -export const auth = new Auth( - { - settings: { - algorithm: "RS256", - privateKey: config.privateKey, - publicKey: config.publicKey, - issuer: "http://localhost", - audience: "http://localhost", - }, - session: z.object({ - accountId: z.string(), - }), - permissions: {} as const, - guards: [], +export const auth = new Auth({ + principal, + resources, + access, + jwt: { + algorithm: "RS256", + privateKey: config.privateKey, + publicKey: config.publicKey, + issuer: "http://localhost", + audience: "http://localhost", }, - { - roles: { - async add(role) { - await db.collection("roles").insertOne(role); - }, +}); - async getById(id) { - const role = await db.collection("roles").findOne({ id }); - if (role === null) { - return undefined; - } - return role; - }, - - async getBySession({ accountId }) { - const account = await db.collection("accounts").findOne({ id: accountId }); - if (account === null) { - return []; - } - return db - .collection("roles") - .find({ id: { $in: account.roles } }) - .toArray(); - }, - - async setPermissions() { - throw new Error("MongoRolesProvider > .setPermissions is managed by Role aggregate projections"); - }, - - async delete(id) { - await db.collection("roles").deleteOne({ id }); - }, - - async assignAccount(roleId: string, accountId: string): Promise { - await db.collection("accounts").updateOne( - { id: accountId }, - { - $push: { - roles: roleId, - }, - }, - ); - }, - - async removeAccount(roleId: string, accountId: string): Promise { - await db.collection("roles").updateOne( - { id: accountId }, - { - $pull: { - roles: roleId, - }, - }, - ); - }, - }, - }, -); - -export type Session = ResolvedSession; -export type Permissions = (typeof auth)["$permissions"]; +export type Session = typeof auth.$session; diff --git a/api/libraries/auth/cerbos.ts b/api/libraries/auth/cerbos.ts new file mode 100644 index 0000000..fa1f598 --- /dev/null +++ b/api/libraries/auth/cerbos.ts @@ -0,0 +1,8 @@ +import { HTTP } from "@cerbos/http"; + +export const cerbos = new HTTP("http://localhost:3592", { + adminCredentials: { + username: "cerbos", + password: "cerbosAdmin", + }, +}); diff --git a/api/libraries/auth/principal.ts b/api/libraries/auth/principal.ts new file mode 100644 index 0000000..1362395 --- /dev/null +++ b/api/libraries/auth/principal.ts @@ -0,0 +1,18 @@ +import { RoleSchema } from "@spec/schemas/account/role.ts"; +import { PrincipalProvider } from "@valkyr/auth"; + +import { db } from "~stores/read-store/database.ts"; + +export const principal = new PrincipalProvider(RoleSchema, {}, async function (id: string) { + const account = await db.collection("accounts").findOne({ id }); + if (account === null) { + return undefined; + } + return { + id, + roles: account.roles, + attributes: {}, + }; +}); + +export type Principal = typeof principal.$principal; diff --git a/api/libraries/auth/resources.ts b/api/libraries/auth/resources.ts new file mode 100644 index 0000000..6bc1b9f --- /dev/null +++ b/api/libraries/auth/resources.ts @@ -0,0 +1,10 @@ +import { ResourceRegistry } from "@valkyr/auth"; + +export const resources = new ResourceRegistry([ + { + kind: "account", + attributes: {}, + }, +] as const); + +export type Resource = typeof resources.$resource; diff --git a/api/libraries/config/libraries/args.ts b/api/libraries/config/libraries/args.ts index 52c3fe1..f43b629 100644 --- a/api/libraries/config/libraries/args.ts +++ b/api/libraries/config/libraries/args.ts @@ -2,9 +2,9 @@ import { parseArgs } from "@std/cli"; import { Parser, toString } from "./parsers.ts"; -export function getArgsVariable(key: string, fallback?: string): string; -export function getArgsVariable(key: string, parse: T, fallback?: string): ReturnType; -export function getArgsVariable(key: string, parse?: T, fallback?: string): ReturnType { +export function getArgsVariable(key: string, fallback?: any): string; +export function getArgsVariable(key: string, parse: T, fallback?: any): ReturnType; +export function getArgsVariable(key: string, parse?: T, fallback?: any): ReturnType { if (typeof parse === "string") { fallback = parse; parse = undefined; @@ -17,5 +17,5 @@ export function getArgsVariable(key: string, parse?: T, fallba } throw new Error(`Config Exception: Missing ${key} variable in arguments`); } - return parse ? parse(value) : toString(value); + return parse ? parse(value) : (toString(value) as any); } diff --git a/api/libraries/config/libraries/environment.ts b/api/libraries/config/libraries/environment.ts index 96920f9..087e384 100644 --- a/api/libraries/config/libraries/environment.ts +++ b/api/libraries/config/libraries/environment.ts @@ -11,9 +11,9 @@ const env = await load(); * @param key - Environment key to resolve. * @param parse - Parser function to convert the value to the desired type. Default: `string`. */ -export function getEnvironmentVariable(key: string, fallback?: string): string; -export function getEnvironmentVariable(key: string, parse: T, fallback?: string): ReturnType; -export function getEnvironmentVariable(key: string, parse?: T, fallback?: string): ReturnType { +export function getEnvironmentVariable(key: string, fallback?: any): string; +export function getEnvironmentVariable(key: string, parse: T, fallback?: any): ReturnType; +export function getEnvironmentVariable(key: string, parse?: T, fallback?: any): ReturnType { if (typeof parse === "string") { fallback = parse; parse = undefined; @@ -25,7 +25,7 @@ export function getEnvironmentVariable(key: string, parse?: T, } throw new Error(`Config Exception: Missing ${key} variable in configuration`); } - return parse ? parse(value) : toString(value); + return parse ? parse(value) : (toString(value) as any); } /** diff --git a/api/libraries/server/api.ts b/api/libraries/server/api.ts index 0c36bfe..8776b70 100644 --- a/api/libraries/server/api.ts +++ b/api/libraries/server/api.ts @@ -166,7 +166,7 @@ export class Api { ); } - if (route.state.access === "session" && req.isAuthenticated === false) { + if (route.state.access === "authenticated" && req.isAuthenticated === false) { return toResponse(new UnauthorizedError(), request); } diff --git a/api/libraries/server/context.ts b/api/libraries/server/context.ts index e030d46..6972d34 100644 --- a/api/libraries/server/context.ts +++ b/api/libraries/server/context.ts @@ -2,7 +2,9 @@ import { ServerContext } from "@spec/relay"; import type { Sockets } from "~libraries/socket/sockets.ts"; +import { Access } from "../auth/access.ts"; import { Session } from "../auth/auth.ts"; +import { Principal } from "../auth/principal.ts"; import { req } from "./request.ts"; declare module "@spec/relay" { @@ -17,17 +19,21 @@ declare module "@spec/relay" { */ isAuthenticated: boolean; - /** - * Get account id from session, throws an error if the request - * does not have a valid session. - */ - accountId: string; - /** * Get request session instance. */ session: Session; + /** + * Get request principal. + */ + principal: Principal; + + /** + * Get access control session. + */ + access: Access; + /** * Sockets instance attached to the server. */ @@ -43,14 +49,18 @@ export function getRequestContext(request: Request): ServerContext { return req.isAuthenticated; }, - get accountId() { - return this.session.accountId; - }, - get session(): Session { return req.session; }, + get principal(): Principal { + return req.session.principal; + }, + + get access(): Access { + return req.session.access; + }, + get sockets(): Sockets { return req.sockets; }, diff --git a/api/libraries/server/request.ts b/api/libraries/server/request.ts index 1a8dad9..a76d5db 100644 --- a/api/libraries/server/request.ts +++ b/api/libraries/server/request.ts @@ -1,11 +1,11 @@ import { InternalServerError, UnauthorizedError } from "@spec/relay"; import { Session } from "../auth/auth.ts"; -import { asyncLocalStorage } from "./storage.ts"; +import { storage } from "./storage.ts"; export const req = { get store() { - const store = asyncLocalStorage.getStore(); + const store = storage.getStore(); if (store === undefined) { throw new InternalServerError("AsyncLocalStorage not defined."); } @@ -55,7 +55,7 @@ export const req = { * Typically used when utility functions might run in and out of request scope. */ getStore() { - return asyncLocalStorage.getStore(); + return storage.getStore(); }, } as const; diff --git a/api/libraries/server/storage.ts b/api/libraries/server/storage.ts index 693aa76..e731db1 100644 --- a/api/libraries/server/storage.ts +++ b/api/libraries/server/storage.ts @@ -3,7 +3,9 @@ import { AsyncLocalStorage } from "node:async_hooks"; import type { Session } from "~libraries/auth/mod.ts"; import type { Sockets } from "~libraries/socket/sockets.ts"; -export const asyncLocalStorage = new AsyncLocalStorage<{ +export const storage = new AsyncLocalStorage(); + +export type Storage = { session?: Session; info: { method: string; @@ -14,4 +16,4 @@ export const asyncLocalStorage = new AsyncLocalStorage<{ response: { headers: Headers; }; -}>(); +}; diff --git a/api/package.json b/api/package.json index 12ca5fe..8d57f43 100644 --- a/api/package.json +++ b/api/package.json @@ -5,20 +5,22 @@ "migrate": "deno run --allow-all .tasks/migrate.ts" }, "dependencies": { - "@felix/bcrypt": "npm:@jsr/felix__bcrypt@1", + "@cerbos/grpc": "0.23.1", + "@cerbos/http": "0.23.1", + "@felix/bcrypt": "npm:@jsr/felix__bcrypt@1.0.5", "@spec/modules": "workspace:*", "@spec/relay": "workspace:*", "@spec/shared": "workspace:*", - "@std/cli": "npm:@jsr/std__cli@1", - "@std/dotenv": "npm:@jsr/std__dotenv@0.225", - "@std/fs": "npm:@jsr/std__fs@1", - "@std/path": "npm:@jsr/std__path@1", - "@valkyr/auth": "npm:@jsr/valkyr__auth@2", - "@valkyr/event-store": "npm:@jsr/valkyr__event-store@2.0.0-beta.6", - "@valkyr/inverse": "npm:@jsr/valkyr__inverse@1", - "@valkyr/json-rpc": "npm:@jsr/valkyr__json-rpc@1", - "cookie": "1", - "mongodb": "6", - "zod": "4" + "@std/cli": "npm:@jsr/std__cli@1.0.22", + "@std/dotenv": "npm:@jsr/std__dotenv@0.225.5", + "@std/fs": "npm:@jsr/std__fs@1.0.19", + "@std/path": "npm:@jsr/std__path@1.1.2", + "@valkyr/auth": "npm:@jsr/valkyr__auth@2.1.3", + "@valkyr/event-store": "npm:@jsr/valkyr__event-store@2", + "@valkyr/inverse": "npm:@jsr/valkyr__inverse@1.0.1", + "@valkyr/json-rpc": "npm:@jsr/valkyr__json-rpc@1.1.0", + "cookie": "1.0.2", + "mongodb": "6.20.0", + "zod": "4.1.9" } } \ No newline at end of file diff --git a/api/routes/account/create.ts b/api/routes/account/create.ts index 60c6bd0..e496ae5 100644 --- a/api/routes/account/create.ts +++ b/api/routes/account/create.ts @@ -13,6 +13,7 @@ export default create.access("public").handle(async ({ body: { name, email } }) .create() .addName(name) .addEmailStrategy(email) + .addRole("user") .save() .then((account) => account.id); }); diff --git a/api/routes/account/get-by-id.ts b/api/routes/account/get-by-id.ts new file mode 100644 index 0000000..7675eec --- /dev/null +++ b/api/routes/account/get-by-id.ts @@ -0,0 +1,17 @@ +import { ForbiddenError } from "@spec/relay/mod.ts"; +import { NotFoundError } from "@spec/relay/mod.ts"; +import { getById } from "@spec/schemas/account/routes.ts"; + +import { db } from "~stores/read-store/database.ts"; + +export default getById.access("authenticated").handle(async ({ params: { id } }, { access }) => { + const account = await db.collection("accounts").findOne({ id }); + if (account === null) { + return new NotFoundError(); + } + const decision = await access.isAllowed({ kind: "account", id: account.id, attributes: {} }, "read"); + if (decision === false) { + return new ForbiddenError(); + } + return account; +}); diff --git a/api/routes/auth/code.ts b/api/routes/auth/code.ts index b89492c..82abdf6 100644 --- a/api/routes/auth/code.ts +++ b/api/routes/auth/code.ts @@ -70,7 +70,7 @@ export default code.access("public").handle(async ({ params: { accountId, codeId status: 302, headers: { location: next, - "set-cookie": cookie.serialize("token", await auth.generate({ accountId: account.id }, "1 week"), options), + "set-cookie": cookie.serialize("token", await auth.generate({ id: account.id }, "1 week"), options), }, }); } @@ -78,7 +78,7 @@ export default code.access("public").handle(async ({ params: { accountId, codeId return new Response(null, { status: 200, headers: { - "set-cookie": cookie.serialize("token", await auth.generate({ accountId: account.id }, "1 week"), options), + "set-cookie": cookie.serialize("token", await auth.generate({ id: account.id }, "1 week"), options), }, }); }); diff --git a/api/routes/auth/password.ts b/api/routes/auth/password.ts index e6afb09..a9249c0 100644 --- a/api/routes/auth/password.ts +++ b/api/routes/auth/password.ts @@ -8,7 +8,7 @@ import { password } from "~libraries/crypto/mod.ts"; import { logger } from "~libraries/logger/mod.ts"; import { getPasswordStrategyByAlias } from "~stores/read-store/methods.ts"; -export default route.handle(async ({ body: { alias, password: userPassword } }) => { +export default route.access("public").handle(async ({ body: { alias, password: userPassword } }) => { const strategy = await getPasswordStrategyByAlias(alias); if (strategy === undefined) { return logger.info({ @@ -28,7 +28,7 @@ export default route.handle(async ({ body: { alias, password: userPassword } }) headers: { "set-cookie": cookie.serialize( "token", - await auth.generate({ accountId: strategy.accountId }, "1 week"), + await auth.generate({ id: strategy.accountId }, "1 week"), config.cookie(1000 * 60 * 60 * 24 * 7), ), }, diff --git a/api/routes/auth/session.ts b/api/routes/auth/session.ts index 6d30732..cd82222 100644 --- a/api/routes/auth/session.ts +++ b/api/routes/auth/session.ts @@ -3,8 +3,8 @@ import { session } from "@spec/schemas/auth/routes.ts"; import { getAccountById } from "~stores/read-store/methods.ts"; -export default session.access("session").handle(async ({ accountId }) => { - const account = await getAccountById(accountId); +export default session.access("authenticated").handle(async ({ principal }) => { + const account = await getAccountById(principal.id); if (account === undefined) { return new UnauthorizedError(); } diff --git a/api/server.ts b/api/server.ts index 53ad0a1..0dd37ab 100644 --- a/api/server.ts +++ b/api/server.ts @@ -3,7 +3,7 @@ import cookie from "cookie"; import { auth, type Session } from "~libraries/auth/mod.ts"; import { logger } from "~libraries/logger/mod.ts"; -import { asyncLocalStorage } from "~libraries/server/mod.ts"; +import { type Storage, storage } from "~libraries/server/mod.ts"; import { Api, resolveRoutes } from "~libraries/server/mod.ts"; import { config } from "./config.ts"; @@ -45,8 +45,6 @@ Deno.serve( async (request) => { const url = new URL(request.url); - // ### Session - let session: Session | undefined; const token = cookie.parse(request.headers.get("cookie") ?? "").token; @@ -63,31 +61,23 @@ Deno.serve( session = resolved; } - // ### Headers - // Set the default headers. - - const headers = new Headers(); - - // ### Handle - - const ts = performance.now(); - - return asyncLocalStorage.run( - { - session, - info: { - method: request.url, - start: Date.now(), - }, - response: { - headers, - }, + const context = { + session, + info: { + method: request.url, + start: Date.now(), }, - async () => { - return api.fetch(request).finally(() => { - log.info(`${request.method} ${url.pathname} [${((performance.now() - ts) / 1000).toLocaleString()} seconds]`); - }); + response: { + headers: new Headers(), }, - ); + } satisfies Storage; + + return storage.run(context, async () => { + return api.fetch(request).finally(() => { + log.info( + `${request.method} ${url.pathname} [${((Date.now() - context.info.start) / 1000).toLocaleString()} seconds]`, + ); + }); + }); }, ); diff --git a/api/stores/event-store/aggregates/account.ts b/api/stores/event-store/aggregates/account.ts index 998e8f1..5c76481 100644 --- a/api/stores/event-store/aggregates/account.ts +++ b/api/stores/event-store/aggregates/account.ts @@ -1,4 +1,5 @@ import { toAccountDocument } from "@spec/schemas/account/account.ts"; +import { Role } from "@spec/schemas/account/role.ts"; import { Strategy } from "@spec/schemas/account/strategies.ts"; import { Avatar } from "@spec/schemas/avatar.ts"; import { Contact } from "@spec/schemas/contact.ts"; @@ -22,6 +23,7 @@ export class Account extends AggregateRoot { emails: [], }; strategies: Strategy[] = []; + roles: Role[] = []; createdAt!: Date; updatedAt!: Date; @@ -51,6 +53,11 @@ export class Account extends AggregateRoot { this.updatedAt = getDate(event.created); break; } + case "account:role:added": { + this.roles.push(event.data); + this.updatedAt = getDate(event.created); + break; + } case "strategy:email:added": { this.strategies.push({ type: "email", value: event.data }); this.updatedAt = getDate(event.created); @@ -103,11 +110,11 @@ export class Account extends AggregateRoot { }); } - addRole(roleId: string, meta: Auditor = systemAuditor): this { + addRole(role: Role, meta: Auditor = systemAuditor): this { return this.push({ stream: this.id, type: "account:role:added", - data: roleId, + data: role, meta, }); } @@ -194,8 +201,8 @@ projector.on("account:email:added", async ({ stream: id, data: email }) => { await db.collection("accounts").updateOne({ id }, { $push: { "contact.emails": email } }); }); -projector.on("account:role:added", async ({ stream: id, data: roleId }) => { - await db.collection("accounts").updateOne({ id }, { $push: { roles: roleId } }); +projector.on("account:role:added", async ({ stream: id, data: role }) => { + await db.collection("accounts").updateOne({ id }, { $push: { roles: role } }); }); projector.on("strategy:email:added", async ({ stream: id, data: email }) => { diff --git a/api/stores/event-store/aggregates/role.ts b/api/stores/event-store/aggregates/role.ts deleted file mode 100644 index 768c209..0000000 --- a/api/stores/event-store/aggregates/role.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { AggregateRoot, getDate, makeAggregateReducer } from "@valkyr/event-store"; - -import { db } from "~libraries/read-store/database.ts"; - -import type { Auditor } from "../events/auditor.ts"; -import { EventStoreFactory } from "../events/mod.ts"; -import type { RoleCreatedData, RolePermissionOperation } from "../events/role.ts"; -import { projector } from "../projector.ts"; - -export class Role extends AggregateRoot { - static override readonly name = "role"; - - id!: string; - - name!: string; - permissions: { [resource: string]: Set } = {}; - - createdAt!: Date; - updatedAt!: Date; - - // ------------------------------------------------------------------------- - // Factories - // ------------------------------------------------------------------------- - - static #reducer = makeAggregateReducer(Role); - - static create(data: RoleCreatedData, meta: Auditor): Role { - return new Role().push({ - type: "role:created", - data, - meta, - }); - } - - static async getById(stream: string): Promise { - return this.$store.reduce({ name: "role", stream, reducer: this.#reducer }); - } - - // ------------------------------------------------------------------------- - // Reducer - // ------------------------------------------------------------------------- - - override with(event: EventStoreFactory["$events"][number]["$record"]): void { - switch (event.type) { - case "role:created": { - this.id = event.stream; - this.createdAt = getDate(event.created); - this.updatedAt = getDate(event.created); - break; - } - case "role:name-set": { - this.name = event.data; - this.updatedAt = getDate(event.created); - break; - } - case "role:permissions-set": { - for (const operation of event.data) { - if (operation.type === "grant") { - if (this.permissions[operation.resource] === undefined) { - this.permissions[operation.resource] = new Set(); - } - this.permissions[operation.resource].add(operation.action); - } - if (operation.type === "deny") { - if (operation.action === undefined) { - delete this.permissions[operation.resource]; - } else { - this.permissions[operation.resource]?.delete(operation.action); - } - } - } - break; - } - } - } - - // ------------------------------------------------------------------------- - // Actions - // ------------------------------------------------------------------------- - - setName(name: string, meta: Auditor): this { - return this.push({ - type: "role:name-set", - stream: this.id, - data: name, - meta, - }); - } - - setPermissions(operations: RolePermissionOperation[], meta: Auditor): this { - return this.push({ - type: "role:permissions-set", - stream: this.id, - data: operations, - meta, - }); - } -} - -/* - |-------------------------------------------------------------------------------- - | Projectors - |-------------------------------------------------------------------------------- - */ - -projector.on("role:created", async ({ stream, data: { name, permissions } }) => { - await db.collection("roles").insertOne({ - id: stream, - name, - permissions: permissions.reduce( - (map, permission) => { - map[permission.resource] = permission.actions; - return map; - }, - {} as Record, - ), - }); -}); diff --git a/api/stores/event-store/events/account.ts b/api/stores/event-store/events/account.ts index 534dfa1..22ca814 100644 --- a/api/stores/event-store/events/account.ts +++ b/api/stores/event-store/events/account.ts @@ -1,3 +1,4 @@ +import { RoleSchema } from "@spec/schemas/account/role.ts"; import { EmailSchema } from "@spec/schemas/email.ts"; import { NameSchema } from "@spec/schemas/name.ts"; import { event } from "@valkyr/event-store"; @@ -10,5 +11,5 @@ export default [ event.type("account:avatar:added").data(z.string()).meta(AuditorSchema), event.type("account:name:added").data(NameSchema).meta(AuditorSchema), event.type("account:email:added").data(EmailSchema).meta(AuditorSchema), - event.type("account:role:added").data(z.string()).meta(AuditorSchema), + event.type("account:role:added").data(RoleSchema).meta(AuditorSchema), ]; diff --git a/api/stores/event-store/events/mod.ts b/api/stores/event-store/events/mod.ts index 3c5f0dc..5313bae 100644 --- a/api/stores/event-store/events/mod.ts +++ b/api/stores/event-store/events/mod.ts @@ -3,9 +3,8 @@ import { EventFactory } from "@valkyr/event-store"; import account from "./account.ts"; import code from "./code.ts"; import organization from "./organization.ts"; -import role from "./role.ts"; import strategy from "./strategy.ts"; -export const events = new EventFactory([...account, ...code, ...organization, ...role, ...strategy]); +export const events = new EventFactory([...account, ...code, ...organization, ...strategy]); export type EventStoreFactory = typeof events; diff --git a/api/stores/event-store/events/role.ts b/api/stores/event-store/events/role.ts deleted file mode 100644 index 957148c..0000000 --- a/api/stores/event-store/events/role.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { event } from "@valkyr/event-store"; -import z from "zod"; - -import { AuditorSchema } from "./auditor.ts"; - -const CreatedSchema = z.object({ - name: z.string(), - permissions: z.array( - z.object({ - resource: z.string(), - actions: z.array(z.string()), - }), - ), -}); - -const OperationSchema = z.discriminatedUnion("type", [ - z.object({ - type: z.literal("grant"), - resource: z.string(), - action: z.string(), - }), - z.object({ - type: z.literal("deny"), - resource: z.string(), - action: z.string().optional(), - }), -]); - -export default [ - event.type("role:created").data(CreatedSchema).meta(AuditorSchema), - event.type("role:name-set").data(z.string()).meta(AuditorSchema), - event.type("role:permissions-set").data(z.array(OperationSchema)).meta(AuditorSchema), -]; - -export type RoleCreatedData = z.infer; - -export type RolePermissionOperation = z.infer; diff --git a/api/stores/read-store/database.ts b/api/stores/read-store/database.ts index 6fbb919..6788d41 100644 --- a/api/stores/read-store/database.ts +++ b/api/stores/read-store/database.ts @@ -1,4 +1,3 @@ -import { RoleDocument } from "@spec/schemas/access/role.ts"; import type { AccountDocument } from "@spec/schemas/account/account.ts"; import { config } from "~config"; @@ -6,7 +5,6 @@ import { getDatabaseAccessor } from "~libraries/database/accessor.ts"; export const db = getDatabaseAccessor<{ accounts: AccountDocument; - roles: RoleDocument; }>(`${config.name}:read-store`); export function takeOne(documents: TDocument[]): TDocument | undefined { diff --git a/apps/react/package.json b/apps/react/package.json index 659a730..34c83c0 100644 --- a/apps/react/package.json +++ b/apps/react/package.json @@ -12,29 +12,29 @@ "dependencies": { "@spec/relay": "workspace:*", "@spec/schemas": "workspace:*", - "@tanstack/react-query": "5", - "@tanstack/react-router": "1", - "@valkyr/db": "npm:@jsr/valkyr__db@2.0.0-beta.3", - "@valkyr/event-emitter": "npm:@jsr/valkyr__event-emitter@1", - "fast-equals": "5", - "react": "19", - "react-dom": "19", - "tailwindcss": "4", - "zod": "4" + "@tanstack/react-query": "5.89.0", + "@tanstack/react-router": "1.131.47", + "@valkyr/db": "npm:@jsr/valkyr__db@2.0.0", + "@valkyr/event-emitter": "npm:@jsr/valkyr__event-emitter@1.0.1", + "fast-equals": "5.2.2", + "react": "19.1.1", + "react-dom": "19.1.1", + "tailwindcss": "4.1.13", + "zod": "4.1.9" }, "devDependencies": { - "@eslint/js": "9", - "@tailwindcss/vite": "4", - "@tanstack/react-router-devtools": "1", - "@types/react": "19", - "@types/react-dom": "19", - "@vitejs/plugin-react": "4", - "eslint": "9", - "eslint-plugin-react-hooks": "5", - "eslint-plugin-react-refresh": "0.4", - "globals": "16", - "typescript": "5", - "typescript-eslint": "8", - "vite": "7" + "@eslint/js": "9.35.0", + "@tailwindcss/vite": "4.1.13", + "@tanstack/react-router-devtools": "1.131.47", + "@types/react": "19.1.13", + "@types/react-dom": "19.1.9", + "@vitejs/plugin-react": "4.7.0", + "eslint": "9.35.0", + "eslint-plugin-react-hooks": "5.2.0", + "eslint-plugin-react-refresh": "0.4.20", + "globals": "16.4.0", + "typescript": "5.9.2", + "typescript-eslint": "8.44.0", + "vite": "7.1.6" } } diff --git a/cerbos/config.yaml b/cerbos/config.yaml new file mode 100644 index 0000000..987413b --- /dev/null +++ b/cerbos/config.yaml @@ -0,0 +1,14 @@ +server: + adminAPI: + enabled: true + adminCredentials: + username: cerbos + passwordHash: JDJ5JDEwJDc5VzBkQ0NUWHFTT3N1OW9xZkx5ZC43M0tuM0JBSTU0dVRsMVBkOEtuYVBCaWFzVXk5d0phCgo= + httpListenAddr: ":3592" + grpcListenAddr: ":3593" + +storage: + driver: disk + disk: + directory: /data/policies + watchForChanges: true diff --git a/cerbos/policies/account.yaml b/cerbos/policies/account.yaml new file mode 100644 index 0000000..c3da02b --- /dev/null +++ b/cerbos/policies/account.yaml @@ -0,0 +1,47 @@ +# yaml-language-server: $schema=https://api.cerbos.dev/latest/cerbos/policy/v1/Policy.schema.json +# docs: https://docs.cerbos.dev/cerbos/latest/policies/resource_policies + +apiVersion: api.cerbos.dev/v1 +resourcePolicy: + resource: account + version: default + rules: + + ### Read + + - actions: + - read + effect: EFFECT_ALLOW + roles: + - admin + + - actions: + - read + effect: EFFECT_ALLOW + roles: + - user + condition: + match: + expr: request.resource.id == request.principal.id + + ### Update + + - actions: + - update + effect: EFFECT_ALLOW + roles: + - user + condition: + match: + expr: request.resource.id == request.principal.id + + ### Delete + + - actions: + - delete + effect: EFFECT_ALLOW + roles: + - user + condition: + match: + expr: request.resource.id == request.principal.id diff --git a/deno.json b/deno.json index c3565f5..8aab12b 100644 --- a/deno.json +++ b/deno.json @@ -21,7 +21,7 @@ "description": "Start react application instance." }, "check": { - "command": "deno check ./mod.ts", + "command": "deno check ./api/server.ts", "description": "Runs a check on all the projects main entry files." }, "lint": { diff --git a/deno.lock b/deno.lock index 682ef00..3dc9eb8 100644 --- a/deno.lock +++ b/deno.lock @@ -1,55 +1,50 @@ { "version": "5", "specifiers": { - "npm:@eslint/js@9": "9.33.0", - "npm:@jsr/felix__bcrypt@1": "1.0.5", - "npm:@jsr/std__assert@1": "1.0.14", - "npm:@jsr/std__cli@1": "1.0.21", - "npm:@jsr/std__dotenv@0.225": "0.225.5", - "npm:@jsr/std__fs@1": "1.0.19", - "npm:@jsr/std__path@1": "1.1.2", - "npm:@jsr/std__testing@1": "1.0.15", - "npm:@jsr/valkyr__auth@2": "2.0.2", - "npm:@jsr/valkyr__db@2.0.0-beta.3": "2.0.0-beta.3", - "npm:@jsr/valkyr__event-emitter@1": "1.0.1", - "npm:@jsr/valkyr__event-store@2.0.0-beta.6": "2.0.0-beta.6", - "npm:@jsr/valkyr__inverse@1": "1.0.1", - "npm:@jsr/valkyr__json-rpc@1": "1.1.0", - "npm:@tailwindcss/vite@4": "4.1.12_vite@7.1.2__picomatch@4.0.3_@types+node@22.15.15", - "npm:@tanstack/react-query@5": "5.85.3_react@19.1.1", - "npm:@tanstack/react-router-devtools@1": "1.131.18_@tanstack+react-router@1.131.18__react@19.1.1__react-dom@19.1.1___react@19.1.1_react@19.1.1_react-dom@19.1.1__react@19.1.1", - "npm:@tanstack/react-router@1": "1.131.18_react@19.1.1_react-dom@19.1.1__react@19.1.1", - "npm:@types/node@*": "22.15.15", - "npm:@types/react-dom@19": "19.1.7_@types+react@19.1.10", - "npm:@types/react@19": "19.1.10", - "npm:@vitejs/plugin-react@4": "4.7.0_vite@7.1.2__picomatch@4.0.3_@babel+core@7.28.3_@types+node@22.15.15", - "npm:cookie@1": "1.0.2", - "npm:eslint-plugin-react-hooks@5": "5.2.0_eslint@9.33.0", - "npm:eslint-plugin-react-refresh@0.4": "0.4.20_eslint@9.33.0", - "npm:eslint-plugin-simple-import-sort@12": "12.1.1_eslint@9.33.0", - "npm:eslint@9": "9.33.0", - "npm:fast-equals@5": "5.2.2", - "npm:globals@16": "16.3.0", - "npm:mongodb@6": "6.18.0", - "npm:path-to-regexp@8": "8.2.0", - "npm:prettier@3": "3.6.2", - "npm:react-dom@19": "19.1.1_react@19.1.1", - "npm:react@19": "19.1.1", - "npm:tailwindcss@4": "4.1.12", - "npm:typescript-eslint@8": "8.39.1_eslint@9.33.0_typescript@5.9.2_@typescript-eslint+parser@8.39.1__eslint@9.33.0__typescript@5.9.2", - "npm:typescript@5": "5.9.2", - "npm:vite@7": "7.1.2_picomatch@4.0.3_@types+node@22.15.15", - "npm:vite@7.1.2": "7.1.2_picomatch@4.0.3_@types+node@22.15.15", - "npm:zod@4": "4.0.17" + "npm:@cerbos/grpc@0.23.1": "0.23.1", + "npm:@cerbos/http@0.23.1": "0.23.1", + "npm:@eslint/js@9.35.0": "9.35.0", + "npm:@jsr/felix__bcrypt@1.0.5": "1.0.5", + "npm:@jsr/std__assert@1.0.14": "1.0.14", + "npm:@jsr/std__cli@1.0.22": "1.0.22", + "npm:@jsr/std__dotenv@0.225.5": "0.225.5", + "npm:@jsr/std__fs@1.0.19": "1.0.19", + "npm:@jsr/std__path@1.1.2": "1.1.2", + "npm:@jsr/std__testing@1.0.15": "1.0.15", + "npm:@jsr/valkyr__auth@2.1.3": "2.1.3", + "npm:@jsr/valkyr__db@2.0.0": "2.0.0", + "npm:@jsr/valkyr__event-emitter@1.0.1": "1.0.1", + "npm:@jsr/valkyr__event-store@2": "2.0.0", + "npm:@jsr/valkyr__inverse@1.0.1": "1.0.1", + "npm:@jsr/valkyr__json-rpc@1.1.0": "1.1.0", + "npm:@tailwindcss/vite@4.1.13": "4.1.13_vite@7.1.6__picomatch@4.0.3_@types+node@24.2.0", + "npm:@tanstack/react-query@5.89.0": "5.89.0_react@19.1.1", + "npm:@tanstack/react-router-devtools@1.131.47": "1.131.47_@tanstack+react-router@1.131.47__react@19.1.1__react-dom@19.1.1___react@19.1.1_react@19.1.1_react-dom@19.1.1__react@19.1.1", + "npm:@tanstack/react-router@1.131.47": "1.131.47_react@19.1.1_react-dom@19.1.1__react@19.1.1", + "npm:@types/node@*": "24.2.0", + "npm:@types/react-dom@19.1.9": "19.1.9_@types+react@19.1.13", + "npm:@types/react@19.1.13": "19.1.13", + "npm:@vitejs/plugin-react@4.7.0": "4.7.0_vite@7.1.6__picomatch@4.0.3_@babel+core@7.28.4_@types+node@24.2.0", + "npm:cookie@1.0.2": "1.0.2", + "npm:eslint-plugin-react-hooks@5.2.0": "5.2.0_eslint@9.35.0", + "npm:eslint-plugin-react-refresh@0.4.20": "0.4.20_eslint@9.35.0", + "npm:eslint-plugin-simple-import-sort@12.1.1": "12.1.1_eslint@9.35.0", + "npm:eslint@9.35.0": "9.35.0", + "npm:fast-equals@5.2.2": "5.2.2", + "npm:globals@16.4.0": "16.4.0", + "npm:mongodb@6.20.0": "6.20.0", + "npm:path-to-regexp@8": "8.3.0", + "npm:prettier@3.6.2": "3.6.2", + "npm:react-dom@19.1.1": "19.1.1_react@19.1.1", + "npm:react@19.1.1": "19.1.1", + "npm:tailwindcss@4.1.13": "4.1.13", + "npm:typescript-eslint@8.44.0": "8.44.0_eslint@9.35.0_typescript@5.9.2_@typescript-eslint+parser@8.44.0__eslint@9.35.0__typescript@5.9.2", + "npm:typescript@5.9.2": "5.9.2", + "npm:vite@7.1.6": "7.1.6_picomatch@4.0.3_@types+node@24.2.0", + "npm:zod@4": "4.1.9", + "npm:zod@4.1.9": "4.1.9" }, "npm": { - "@ampproject/remapping@2.3.0": { - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dependencies": [ - "@jridgewell/gen-mapping", - "@jridgewell/trace-mapping" - ] - }, "@babel/code-frame@7.27.1": { "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", "dependencies": [ @@ -58,13 +53,12 @@ "picocolors" ] }, - "@babel/compat-data@7.28.0": { - "integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==" + "@babel/compat-data@7.28.4": { + "integrity": "sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==" }, - "@babel/core@7.28.3": { - "integrity": "sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ==", + "@babel/core@7.28.4": { + "integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==", "dependencies": [ - "@ampproject/remapping", "@babel/code-frame", "@babel/generator", "@babel/helper-compilation-targets", @@ -74,6 +68,7 @@ "@babel/template", "@babel/traverse", "@babel/types", + "@jridgewell/remapping", "convert-source-map", "debug", "gensync", @@ -111,7 +106,7 @@ "@babel/types" ] }, - "@babel/helper-module-transforms@7.28.3_@babel+core@7.28.3": { + "@babel/helper-module-transforms@7.28.3_@babel+core@7.28.4": { "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", "dependencies": [ "@babel/core", @@ -132,28 +127,28 @@ "@babel/helper-validator-option@7.27.1": { "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==" }, - "@babel/helpers@7.28.3": { - "integrity": "sha512-PTNtvUQihsAsDHMOP5pfobP8C6CM4JWXmP8DrEIt46c3r2bf87Ua1zoqevsMo9g+tWDwgWrFP5EIxuBx5RudAw==", + "@babel/helpers@7.28.4": { + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", "dependencies": [ "@babel/template", "@babel/types" ] }, - "@babel/parser@7.28.3": { - "integrity": "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==", + "@babel/parser@7.28.4": { + "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", "dependencies": [ "@babel/types" ], "bin": true }, - "@babel/plugin-transform-react-jsx-self@7.27.1_@babel+core@7.28.3": { + "@babel/plugin-transform-react-jsx-self@7.27.1_@babel+core@7.28.4": { "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-react-jsx-source@7.27.1_@babel+core@7.28.3": { + "@babel/plugin-transform-react-jsx-source@7.27.1_@babel+core@7.28.4": { "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", "dependencies": [ "@babel/core", @@ -168,8 +163,8 @@ "@babel/types" ] }, - "@babel/traverse@7.28.3": { - "integrity": "sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ==", + "@babel/traverse@7.28.4": { + "integrity": "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==", "dependencies": [ "@babel/code-frame", "@babel/generator", @@ -180,164 +175,169 @@ "debug" ] }, - "@babel/types@7.28.2": { - "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", + "@babel/types@7.28.4": { + "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", "dependencies": [ "@babel/helper-string-parser", "@babel/helper-validator-identifier" ] }, - "@emnapi/core@1.4.5": { - "integrity": "sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q==", + "@bufbuild/protobuf@2.9.0": { + "integrity": "sha512-rnJenoStJ8nvmt9Gzye8nkYd6V22xUAnu4086ER7h1zJ508vStko4pMvDeQ446ilDTFpV5wnoc5YS7XvMwwMqA==" + }, + "@cerbos/core@0.24.1": { + "integrity": "sha512-Gt9ETQR3WDVcPlxN+HiGUDtNgWFulwS5ZjBgzJFsdb7e2GCw0tOPE9Ex1qHNZvG/0JHpFWJWIiYaSKyXcp35YQ==", "dependencies": [ - "@emnapi/wasi-threads", - "tslib" + "uuid" ] }, - "@emnapi/runtime@1.4.5": { - "integrity": "sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==", + "@cerbos/grpc@0.23.1": { + "integrity": "sha512-6ve6d9m+hBZ4xZAI6Oc2/TR2RAoy+QE8zmTVNt38MMyif+BJ3T2dD/Lwd5t75+9+pBJCLch5kLz5ZtnbnGoyuw==", "dependencies": [ - "tslib" + "@bufbuild/protobuf", + "@cerbos/core", + "@grpc/grpc-js" ] }, - "@emnapi/wasi-threads@1.0.4": { - "integrity": "sha512-PJR+bOmMOPH8AtcTGAyYNiuJ3/Fcoj2XN/gBEWzDIKh254XO+mM9XoXHk5GNEhodxeMznbg7BlRojVbKN+gC6g==", + "@cerbos/http@0.23.1": { + "integrity": "sha512-XzWFS6L7M+oUnjGEFIoQygtlmZy3zOpUobN6spGp1MAaT6GQJMRFK8P8xhY2BQjTIhqYgnoiEFOAULTkbgNIjg==", "dependencies": [ - "tslib" + "@cerbos/core", + "qs" ] }, - "@esbuild/aix-ppc64@0.25.9": { - "integrity": "sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==", + "@esbuild/aix-ppc64@0.25.10": { + "integrity": "sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==", "os": ["aix"], "cpu": ["ppc64"] }, - "@esbuild/android-arm64@0.25.9": { - "integrity": "sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==", + "@esbuild/android-arm64@0.25.10": { + "integrity": "sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==", "os": ["android"], "cpu": ["arm64"] }, - "@esbuild/android-arm@0.25.9": { - "integrity": "sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==", + "@esbuild/android-arm@0.25.10": { + "integrity": "sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==", "os": ["android"], "cpu": ["arm"] }, - "@esbuild/android-x64@0.25.9": { - "integrity": "sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==", + "@esbuild/android-x64@0.25.10": { + "integrity": "sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==", "os": ["android"], "cpu": ["x64"] }, - "@esbuild/darwin-arm64@0.25.9": { - "integrity": "sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==", + "@esbuild/darwin-arm64@0.25.10": { + "integrity": "sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==", "os": ["darwin"], "cpu": ["arm64"] }, - "@esbuild/darwin-x64@0.25.9": { - "integrity": "sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==", + "@esbuild/darwin-x64@0.25.10": { + "integrity": "sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==", "os": ["darwin"], "cpu": ["x64"] }, - "@esbuild/freebsd-arm64@0.25.9": { - "integrity": "sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==", + "@esbuild/freebsd-arm64@0.25.10": { + "integrity": "sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==", "os": ["freebsd"], "cpu": ["arm64"] }, - "@esbuild/freebsd-x64@0.25.9": { - "integrity": "sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==", + "@esbuild/freebsd-x64@0.25.10": { + "integrity": "sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==", "os": ["freebsd"], "cpu": ["x64"] }, - "@esbuild/linux-arm64@0.25.9": { - "integrity": "sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==", + "@esbuild/linux-arm64@0.25.10": { + "integrity": "sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==", "os": ["linux"], "cpu": ["arm64"] }, - "@esbuild/linux-arm@0.25.9": { - "integrity": "sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==", + "@esbuild/linux-arm@0.25.10": { + "integrity": "sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==", "os": ["linux"], "cpu": ["arm"] }, - "@esbuild/linux-ia32@0.25.9": { - "integrity": "sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==", + "@esbuild/linux-ia32@0.25.10": { + "integrity": "sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==", "os": ["linux"], "cpu": ["ia32"] }, - "@esbuild/linux-loong64@0.25.9": { - "integrity": "sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==", + "@esbuild/linux-loong64@0.25.10": { + "integrity": "sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==", "os": ["linux"], "cpu": ["loong64"] }, - "@esbuild/linux-mips64el@0.25.9": { - "integrity": "sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==", + "@esbuild/linux-mips64el@0.25.10": { + "integrity": "sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==", "os": ["linux"], "cpu": ["mips64el"] }, - "@esbuild/linux-ppc64@0.25.9": { - "integrity": "sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==", + "@esbuild/linux-ppc64@0.25.10": { + "integrity": "sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==", "os": ["linux"], "cpu": ["ppc64"] }, - "@esbuild/linux-riscv64@0.25.9": { - "integrity": "sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==", + "@esbuild/linux-riscv64@0.25.10": { + "integrity": "sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==", "os": ["linux"], "cpu": ["riscv64"] }, - "@esbuild/linux-s390x@0.25.9": { - "integrity": "sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==", + "@esbuild/linux-s390x@0.25.10": { + "integrity": "sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==", "os": ["linux"], "cpu": ["s390x"] }, - "@esbuild/linux-x64@0.25.9": { - "integrity": "sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==", + "@esbuild/linux-x64@0.25.10": { + "integrity": "sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==", "os": ["linux"], "cpu": ["x64"] }, - "@esbuild/netbsd-arm64@0.25.9": { - "integrity": "sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==", + "@esbuild/netbsd-arm64@0.25.10": { + "integrity": "sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==", "os": ["netbsd"], "cpu": ["arm64"] }, - "@esbuild/netbsd-x64@0.25.9": { - "integrity": "sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==", + "@esbuild/netbsd-x64@0.25.10": { + "integrity": "sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==", "os": ["netbsd"], "cpu": ["x64"] }, - "@esbuild/openbsd-arm64@0.25.9": { - "integrity": "sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==", + "@esbuild/openbsd-arm64@0.25.10": { + "integrity": "sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==", "os": ["openbsd"], "cpu": ["arm64"] }, - "@esbuild/openbsd-x64@0.25.9": { - "integrity": "sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==", + "@esbuild/openbsd-x64@0.25.10": { + "integrity": "sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==", "os": ["openbsd"], "cpu": ["x64"] }, - "@esbuild/openharmony-arm64@0.25.9": { - "integrity": "sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==", + "@esbuild/openharmony-arm64@0.25.10": { + "integrity": "sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==", "os": ["openharmony"], "cpu": ["arm64"] }, - "@esbuild/sunos-x64@0.25.9": { - "integrity": "sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==", + "@esbuild/sunos-x64@0.25.10": { + "integrity": "sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==", "os": ["sunos"], "cpu": ["x64"] }, - "@esbuild/win32-arm64@0.25.9": { - "integrity": "sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==", + "@esbuild/win32-arm64@0.25.10": { + "integrity": "sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==", "os": ["win32"], "cpu": ["arm64"] }, - "@esbuild/win32-ia32@0.25.9": { - "integrity": "sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==", + "@esbuild/win32-ia32@0.25.10": { + "integrity": "sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==", "os": ["win32"], "cpu": ["ia32"] }, - "@esbuild/win32-x64@0.25.9": { - "integrity": "sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==", + "@esbuild/win32-x64@0.25.10": { + "integrity": "sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==", "os": ["win32"], "cpu": ["x64"] }, - "@eslint-community/eslint-utils@4.7.0_eslint@9.33.0": { - "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", + "@eslint-community/eslint-utils@4.9.0_eslint@9.35.0": { + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", "dependencies": [ "eslint", "eslint-visitor-keys@3.4.3" @@ -377,8 +377,8 @@ "strip-json-comments" ] }, - "@eslint/js@9.33.0": { - "integrity": "sha512-5K1/mKhWaMfreBGJTwval43JJmkip0RmM+3+IuqupeSKNC/Th2Kc7ucaq5ovTSra/OOKB9c58CGSz3QMVbWt0A==" + "@eslint/js@9.35.0": { + "integrity": "sha512-30iXE9whjlILfWobBkNerJo+TXYsgVM5ERQwMcMKCHckHflCmf7wXDAHlARoWnh0s1U72WqlbeyE7iAcCzuCPw==" }, "@eslint/object-schema@2.1.6": { "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==" @@ -390,22 +390,36 @@ "levn" ] }, + "@grpc/grpc-js@1.14.0": { + "integrity": "sha512-N8Jx6PaYzcTRNzirReJCtADVoq4z7+1KQ4E70jTg/koQiMoUSN1kbNjPOqpPbhMFhfU1/l7ixspPl8dNY+FoUg==", + "dependencies": [ + "@grpc/proto-loader", + "@js-sdsl/ordered-map" + ] + }, + "@grpc/proto-loader@0.8.0": { + "integrity": "sha512-rc1hOQtjIWGxcxpb9aHAfLpIctjEnsDehj0DAiVfBlmT84uvR0uUtN2hEi/ecvWVjXUGf5qPF4qEgiLOx1YIMQ==", + "dependencies": [ + "lodash.camelcase", + "long", + "protobufjs", + "yargs" + ], + "bin": true + }, "@humanfs/core@0.19.1": { "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==" }, - "@humanfs/node@0.16.6": { - "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "@humanfs/node@0.16.7": { + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", "dependencies": [ "@humanfs/core", - "@humanwhocodes/retry@0.3.1" + "@humanwhocodes/retry" ] }, "@humanwhocodes/module-importer@1.0.1": { "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==" }, - "@humanwhocodes/retry@0.3.1": { - "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==" - }, "@humanwhocodes/retry@0.4.3": { "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==" }, @@ -435,13 +449,16 @@ "@jridgewell/sourcemap-codec@1.5.5": { "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==" }, - "@jridgewell/trace-mapping@0.3.30": { - "integrity": "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==", + "@jridgewell/trace-mapping@0.3.31": { + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "dependencies": [ "@jridgewell/resolve-uri", "@jridgewell/sourcemap-codec" ] }, + "@js-sdsl/ordered-map@4.4.2": { + "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==" + }, "@jsr/denosaurs__plug@1.1.0": { "integrity": "sha512-GNRMr8XcYWbv8C1B5OjDa5u8q3p2lz7YVWQLhH5HAy0pkpb0+Y3npSxzjM49v5ajTFIzUCwIKv1gQukPm9q7qw==", "dependencies": [ @@ -470,9 +487,9 @@ "integrity": "sha512-aIG8W3TOmW+lKdAJA5w56qASu9EiUmBXbhW6eAlSEUBid+KVESGqQygFFg+awt/c8K+qobVM6M/u3SbIy0NyUQ==", "tarball": "https://npm.jsr.io/~/11/@jsr/std__async/1.0.14.tgz" }, - "@jsr/std__cli@1.0.21": { - "integrity": "sha512-sx/iCW12GUITEkiNmdj7LbM6q/oWq9JoHz24Q/VxPMlLSXKeS5y7teBEDbWSqxFGIevKfgYJYlsbcHWNumd7fw==", - "tarball": "https://npm.jsr.io/~/11/@jsr/std__cli/1.0.21.tgz" + "@jsr/std__cli@1.0.22": { + "integrity": "sha512-PQkNPxuo8nOby8RgRxaLrQ9UAem/cCYKZYznV1fISZAzBbxMVBfsIeHA9FxMH0OUuRcu4ReEZ9QudeGg6xLdvw==", + "tarball": "https://npm.jsr.io/~/11/@jsr/std__cli/1.0.22.tgz" }, "@jsr/std__data-structures@1.0.9": { "integrity": "sha512-+mT4Nll6fx+CPNqrlC+huhIOYNSMS+KUdJ4B8NujiQrh/bq++ds5PXpEsfV5EPR+YuWcuDGG0P1DE+Rednd7Wg==", @@ -505,9 +522,9 @@ "integrity": "sha512-fmD6yKep/sMnB2yPQU/REZG7Z4N9SZwcUBNnceo4QkXk67l3JEfxHoROQ/YHeVSOmq6x55Ra6nuMjz2ib3nj3g==", "tarball": "https://npm.jsr.io/~/11/@jsr/std__internal/1.0.10.tgz" }, - "@jsr/std__net@1.0.5": { - "integrity": "sha512-Cz5vyNbeUH3AAEqTyo2dmiqlTXnSAm+z9W3sZKzc0eq028AmT4Vb+/3BprlAJ5vQH+tRrDBz3+6jm0C+ONxEyw==", - "tarball": "https://npm.jsr.io/~/11/@jsr/std__net/1.0.5.tgz" + "@jsr/std__net@1.0.6": { + "integrity": "sha512-mh27Fw4UMCjGSIMoOhjia5cS5fNP9M9DZYhGB7EYSZNnzf/eguFiarii/W4oDwYMmnxCMouUzhc6Y7jFuwTzcg==", + "tarball": "https://npm.jsr.io/~/11/@jsr/std__net/1.0.6.tgz" }, "@jsr/std__path@1.1.2": { "integrity": "sha512-5hkOR1s5M7am02Bn9KS+SNMNwUSivz7t7/w2HBhFIfO7Eh8+mWilaZ+1tdanV9aaSHr4c99Zo4Da+cCSuzUOdA==", @@ -528,23 +545,23 @@ ], "tarball": "https://npm.jsr.io/~/11/@jsr/std__testing/1.0.15.tgz" }, - "@jsr/valkyr__auth@2.0.2": { - "integrity": "sha512-wxSWL0BUTXeVamCcpSYoMFceUMl/IKa/52aFtbtvMaprZiS6e4JHHU/tsFR72RjHn8RBGFLRnS/ttBIZlQM/Yg==", + "@jsr/valkyr__auth@2.1.3": { + "integrity": "sha512-J2r6bfd2IMoVtln/valsagVh9LDBLG2tBzfxBHoi+6NZzA0g3DAHevC2Rf8TTsMDFSiqz3ewUgntBnmMpR9SVA==", "dependencies": [ "jose", - "zod@3.25.0-beta.20250519T094321" + "zod" ], - "tarball": "https://npm.jsr.io/~/11/@jsr/valkyr__auth/2.0.2.tgz" + "tarball": "https://npm.jsr.io/~/11/@jsr/valkyr__auth/2.1.3.tgz" }, - "@jsr/valkyr__db@2.0.0-beta.3": { - "integrity": "sha512-aY04em3aYkidlmUzxgVBJjdLEVhUPEtZHUJwFb35hPtUedTIrs1k9Em5s2OzSP18MWHxA9RmoS7EXX/4VkEBtw==", + "@jsr/valkyr__db@2.0.0": { + "integrity": "sha512-0gIauba+vQW6ssqMACLO1Z/METlhzoX+y4t9Sawh/IafQ986Rgvp6gCI+WArp7vbsO5hpItixrqjkxnnNC+h5g==", "dependencies": [ "bson", - "idb@8.0.3", - "mingo@6.6.1", - "rxjs@7.8.2" + "idb", + "mingo", + "rxjs" ], - "tarball": "https://npm.jsr.io/~/11/@jsr/valkyr__db/2.0.0-beta.3.tgz" + "tarball": "https://npm.jsr.io/~/11/@jsr/valkyr__db/2.0.0.tgz" }, "@jsr/valkyr__event-emitter@1.0.1": { "integrity": "sha512-mre5tWJddz8LylSQWuLOw3zgIxd2JmhGRV46jKXNPCGzY2NKJwGGT9H7SBw36RV4dW7jnnH2U1aCJkh8IS/pzA==", @@ -553,16 +570,16 @@ ], "tarball": "https://npm.jsr.io/~/11/@jsr/valkyr__event-emitter/1.0.1.tgz" }, - "@jsr/valkyr__event-store@2.0.0-beta.6": { - "integrity": "sha512-4ybdvjW2SIXPy9WOwG0UyCEu4XYsrorL5ATGgZmKFDLzhlhrLDMlmDSzpMouPEOBlEFohR4080rvWRD0bCe/pA==", + "@jsr/valkyr__event-store@2.0.0": { + "integrity": "sha512-izGy/QIGQXoTz0PP1UinSWcSPEEpNuePbmApBbvHq6MFp1p2X/k2eDPKlz2txwXcIn+QKjDhE5F59xPNEKnIng==", "dependencies": [ + "@jsr/valkyr__db", "@jsr/valkyr__testcontainers", - "@valkyr/db", "mongodb", "postgres", - "zod@4.0.17" + "zod" ], - "tarball": "https://npm.jsr.io/~/11/@jsr/valkyr__event-store/2.0.0-beta.6.tgz" + "tarball": "https://npm.jsr.io/~/11/@jsr/valkyr__event-store/2.0.0.tgz" }, "@jsr/valkyr__inverse@1.0.1": { "integrity": "sha512-uZpzPct9FGobgl6H+iR3VJlzZbTFVmJSrB4z5In8zHgIJCkmgYj0diU3soU6MuiKR7SFBfD4PGSuUpTTJHNMlg==", @@ -592,14 +609,6 @@ "sparse-bitfield" ] }, - "@napi-rs/wasm-runtime@0.2.12": { - "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", - "dependencies": [ - "@emnapi/core", - "@emnapi/runtime", - "@tybys/wasm-util" - ] - }, "@nodelib/fs.scandir@2.1.5": { "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dependencies": [ @@ -617,111 +626,150 @@ "fastq" ] }, + "@protobufjs/aspromise@1.1.2": { + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + }, + "@protobufjs/base64@1.1.2": { + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "@protobufjs/codegen@2.0.4": { + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "@protobufjs/eventemitter@1.1.0": { + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + }, + "@protobufjs/fetch@1.1.0": { + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "dependencies": [ + "@protobufjs/aspromise", + "@protobufjs/inquire" + ] + }, + "@protobufjs/float@1.0.2": { + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + }, + "@protobufjs/inquire@1.1.0": { + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + }, + "@protobufjs/path@1.1.2": { + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + }, + "@protobufjs/pool@1.1.0": { + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + }, + "@protobufjs/utf8@1.1.0": { + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, "@rolldown/pluginutils@1.0.0-beta.27": { "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==" }, - "@rollup/rollup-android-arm-eabi@4.46.2": { - "integrity": "sha512-Zj3Hl6sN34xJtMv7Anwb5Gu01yujyE/cLBDB2gnHTAHaWS1Z38L7kuSG+oAh0giZMqG060f/YBStXtMH6FvPMA==", + "@rollup/rollup-android-arm-eabi@4.50.2": { + "integrity": "sha512-uLN8NAiFVIRKX9ZQha8wy6UUs06UNSZ32xj6giK/rmMXAgKahwExvK6SsmgU5/brh4w/nSgj8e0k3c1HBQpa0A==", "os": ["android"], "cpu": ["arm"] }, - "@rollup/rollup-android-arm64@4.46.2": { - "integrity": "sha512-nTeCWY83kN64oQ5MGz3CgtPx8NSOhC5lWtsjTs+8JAJNLcP3QbLCtDDgUKQc/Ro/frpMq4SHUaHN6AMltcEoLQ==", + "@rollup/rollup-android-arm64@4.50.2": { + "integrity": "sha512-oEouqQk2/zxxj22PNcGSskya+3kV0ZKH+nQxuCCOGJ4oTXBdNTbv+f/E3c74cNLeMO1S5wVWacSws10TTSB77g==", "os": ["android"], "cpu": ["arm64"] }, - "@rollup/rollup-darwin-arm64@4.46.2": { - "integrity": "sha512-HV7bW2Fb/F5KPdM/9bApunQh68YVDU8sO8BvcW9OngQVN3HHHkw99wFupuUJfGR9pYLLAjcAOA6iO+evsbBaPQ==", + "@rollup/rollup-darwin-arm64@4.50.2": { + "integrity": "sha512-OZuTVTpj3CDSIxmPgGH8en/XtirV5nfljHZ3wrNwvgkT5DQLhIKAeuFSiwtbMto6oVexV0k1F1zqURPKf5rI1Q==", "os": ["darwin"], "cpu": ["arm64"] }, - "@rollup/rollup-darwin-x64@4.46.2": { - "integrity": "sha512-SSj8TlYV5nJixSsm/y3QXfhspSiLYP11zpfwp6G/YDXctf3Xkdnk4woJIF5VQe0of2OjzTt8EsxnJDCdHd2xMA==", + "@rollup/rollup-darwin-x64@4.50.2": { + "integrity": "sha512-Wa/Wn8RFkIkr1vy1k1PB//VYhLnlnn5eaJkfTQKivirOvzu5uVd2It01ukeQstMursuz7S1bU+8WW+1UPXpa8A==", "os": ["darwin"], "cpu": ["x64"] }, - "@rollup/rollup-freebsd-arm64@4.46.2": { - "integrity": "sha512-ZyrsG4TIT9xnOlLsSSi9w/X29tCbK1yegE49RYm3tu3wF1L/B6LVMqnEWyDB26d9Ecx9zrmXCiPmIabVuLmNSg==", + "@rollup/rollup-freebsd-arm64@4.50.2": { + "integrity": "sha512-QkzxvH3kYN9J1w7D1A+yIMdI1pPekD+pWx7G5rXgnIlQ1TVYVC6hLl7SOV9pi5q9uIDF9AuIGkuzcbF7+fAhow==", "os": ["freebsd"], "cpu": ["arm64"] }, - "@rollup/rollup-freebsd-x64@4.46.2": { - "integrity": "sha512-pCgHFoOECwVCJ5GFq8+gR8SBKnMO+xe5UEqbemxBpCKYQddRQMgomv1104RnLSg7nNvgKy05sLsY51+OVRyiVw==", + "@rollup/rollup-freebsd-x64@4.50.2": { + "integrity": "sha512-dkYXB0c2XAS3a3jmyDkX4Jk0m7gWLFzq1C3qUnJJ38AyxIF5G/dyS4N9B30nvFseCfgtCEdbYFhk0ChoCGxPog==", "os": ["freebsd"], "cpu": ["x64"] }, - "@rollup/rollup-linux-arm-gnueabihf@4.46.2": { - "integrity": "sha512-EtP8aquZ0xQg0ETFcxUbU71MZlHaw9MChwrQzatiE8U/bvi5uv/oChExXC4mWhjiqK7azGJBqU0tt5H123SzVA==", + "@rollup/rollup-linux-arm-gnueabihf@4.50.2": { + "integrity": "sha512-9VlPY/BN3AgbukfVHAB8zNFWB/lKEuvzRo1NKev0Po8sYFKx0i+AQlCYftgEjcL43F2h9Ui1ZSdVBc4En/sP2w==", "os": ["linux"], "cpu": ["arm"] }, - "@rollup/rollup-linux-arm-musleabihf@4.46.2": { - "integrity": "sha512-qO7F7U3u1nfxYRPM8HqFtLd+raev2K137dsV08q/LRKRLEc7RsiDWihUnrINdsWQxPR9jqZ8DIIZ1zJJAm5PjQ==", + "@rollup/rollup-linux-arm-musleabihf@4.50.2": { + "integrity": "sha512-+GdKWOvsifaYNlIVf07QYan1J5F141+vGm5/Y8b9uCZnG/nxoGqgCmR24mv0koIWWuqvFYnbURRqw1lv7IBINw==", "os": ["linux"], "cpu": ["arm"] }, - "@rollup/rollup-linux-arm64-gnu@4.46.2": { - "integrity": "sha512-3dRaqLfcOXYsfvw5xMrxAk9Lb1f395gkoBYzSFcc/scgRFptRXL9DOaDpMiehf9CO8ZDRJW2z45b6fpU5nwjng==", + "@rollup/rollup-linux-arm64-gnu@4.50.2": { + "integrity": "sha512-df0Eou14ojtUdLQdPFnymEQteENwSJAdLf5KCDrmZNsy1c3YaCNaJvYsEUHnrg+/DLBH612/R0xd3dD03uz2dg==", "os": ["linux"], "cpu": ["arm64"] }, - "@rollup/rollup-linux-arm64-musl@4.46.2": { - "integrity": "sha512-fhHFTutA7SM+IrR6lIfiHskxmpmPTJUXpWIsBXpeEwNgZzZZSg/q4i6FU4J8qOGyJ0TR+wXBwx/L7Ho9z0+uDg==", + "@rollup/rollup-linux-arm64-musl@4.50.2": { + "integrity": "sha512-iPeouV0UIDtz8j1YFR4OJ/zf7evjauqv7jQ/EFs0ClIyL+by++hiaDAfFipjOgyz6y6xbDvJuiU4HwpVMpRFDQ==", "os": ["linux"], "cpu": ["arm64"] }, - "@rollup/rollup-linux-loongarch64-gnu@4.46.2": { - "integrity": "sha512-i7wfGFXu8x4+FRqPymzjD+Hyav8l95UIZ773j7J7zRYc3Xsxy2wIn4x+llpunexXe6laaO72iEjeeGyUFmjKeA==", + "@rollup/rollup-linux-loong64-gnu@4.50.2": { + "integrity": "sha512-OL6KaNvBopLlj5fTa5D5bau4W82f+1TyTZRr2BdnfsrnQnmdxh4okMxR2DcDkJuh4KeoQZVuvHvzuD/lyLn2Kw==", "os": ["linux"], "cpu": ["loong64"] }, - "@rollup/rollup-linux-ppc64-gnu@4.46.2": { - "integrity": "sha512-B/l0dFcHVUnqcGZWKcWBSV2PF01YUt0Rvlurci5P+neqY/yMKchGU8ullZvIv5e8Y1C6wOn+U03mrDylP5q9Yw==", + "@rollup/rollup-linux-ppc64-gnu@4.50.2": { + "integrity": "sha512-I21VJl1w6z/K5OTRl6aS9DDsqezEZ/yKpbqlvfHbW0CEF5IL8ATBMuUx6/mp683rKTK8thjs/0BaNrZLXetLag==", "os": ["linux"], "cpu": ["ppc64"] }, - "@rollup/rollup-linux-riscv64-gnu@4.46.2": { - "integrity": "sha512-32k4ENb5ygtkMwPMucAb8MtV8olkPT03oiTxJbgkJa7lJ7dZMr0GCFJlyvy+K8iq7F/iuOr41ZdUHaOiqyR3iQ==", + "@rollup/rollup-linux-riscv64-gnu@4.50.2": { + "integrity": "sha512-Hq6aQJT/qFFHrYMjS20nV+9SKrXL2lvFBENZoKfoTH2kKDOJqff5OSJr4x72ZaG/uUn+XmBnGhfr4lwMRrmqCQ==", "os": ["linux"], "cpu": ["riscv64"] }, - "@rollup/rollup-linux-riscv64-musl@4.46.2": { - "integrity": "sha512-t5B2loThlFEauloaQkZg9gxV05BYeITLvLkWOkRXogP4qHXLkWSbSHKM9S6H1schf/0YGP/qNKtiISlxvfmmZw==", + "@rollup/rollup-linux-riscv64-musl@4.50.2": { + "integrity": "sha512-82rBSEXRv5qtKyr0xZ/YMF531oj2AIpLZkeNYxmKNN6I2sVE9PGegN99tYDLK2fYHJITL1P2Lgb4ZXnv0PjQvw==", "os": ["linux"], "cpu": ["riscv64"] }, - "@rollup/rollup-linux-s390x-gnu@4.46.2": { - "integrity": "sha512-YKjekwTEKgbB7n17gmODSmJVUIvj8CX7q5442/CK80L8nqOUbMtf8b01QkG3jOqyr1rotrAnW6B/qiHwfcuWQA==", + "@rollup/rollup-linux-s390x-gnu@4.50.2": { + "integrity": "sha512-4Q3S3Hy7pC6uaRo9gtXUTJ+EKo9AKs3BXKc2jYypEcMQ49gDPFU2P1ariX9SEtBzE5egIX6fSUmbmGazwBVF9w==", "os": ["linux"], "cpu": ["s390x"] }, - "@rollup/rollup-linux-x64-gnu@4.46.2": { - "integrity": "sha512-Jj5a9RUoe5ra+MEyERkDKLwTXVu6s3aACP51nkfnK9wJTraCC8IMe3snOfALkrjTYd2G1ViE1hICj0fZ7ALBPA==", + "@rollup/rollup-linux-x64-gnu@4.50.2": { + "integrity": "sha512-9Jie/At6qk70dNIcopcL4p+1UirusEtznpNtcq/u/C5cC4HBX7qSGsYIcG6bdxj15EYWhHiu02YvmdPzylIZlA==", "os": ["linux"], "cpu": ["x64"] }, - "@rollup/rollup-linux-x64-musl@4.46.2": { - "integrity": "sha512-7kX69DIrBeD7yNp4A5b81izs8BqoZkCIaxQaOpumcJ1S/kmqNFjPhDu1LHeVXv0SexfHQv5cqHsxLOjETuqDuA==", + "@rollup/rollup-linux-x64-musl@4.50.2": { + "integrity": "sha512-HPNJwxPL3EmhzeAnsWQCM3DcoqOz3/IC6de9rWfGR8ZCuEHETi9km66bH/wG3YH0V3nyzyFEGUZeL5PKyy4xvw==", "os": ["linux"], "cpu": ["x64"] }, - "@rollup/rollup-win32-arm64-msvc@4.46.2": { - "integrity": "sha512-wiJWMIpeaak/jsbaq2HMh/rzZxHVW1rU6coyeNNpMwk5isiPjSTx0a4YLSlYDwBH/WBvLz+EtsNqQScZTLJy3g==", + "@rollup/rollup-openharmony-arm64@4.50.2": { + "integrity": "sha512-nMKvq6FRHSzYfKLHZ+cChowlEkR2lj/V0jYj9JnGUVPL2/mIeFGmVM2mLaFeNa5Jev7W7TovXqXIG2d39y1KYA==", + "os": ["openharmony"], + "cpu": ["arm64"] + }, + "@rollup/rollup-win32-arm64-msvc@4.50.2": { + "integrity": "sha512-eFUvvnTYEKeTyHEijQKz81bLrUQOXKZqECeiWH6tb8eXXbZk+CXSG2aFrig2BQ/pjiVRj36zysjgILkqarS2YA==", "os": ["win32"], "cpu": ["arm64"] }, - "@rollup/rollup-win32-ia32-msvc@4.46.2": { - "integrity": "sha512-gBgaUDESVzMgWZhcyjfs9QFK16D8K6QZpwAaVNJxYDLHWayOta4ZMjGm/vsAEy3hvlS2GosVFlBlP9/Wb85DqQ==", + "@rollup/rollup-win32-ia32-msvc@4.50.2": { + "integrity": "sha512-cBaWmXqyfRhH8zmUxK3d3sAhEWLrtMjWBRwdMMHJIXSjvjLKvv49adxiEz+FJ8AP90apSDDBx2Tyd/WylV6ikA==", "os": ["win32"], "cpu": ["ia32"] }, - "@rollup/rollup-win32-x64-msvc@4.46.2": { - "integrity": "sha512-CvUo2ixeIQGtF6WvuB87XWqPQkoFAFqW+HUo/WzHwuHDvIwZCtjdWXoYCcr06iKGydiqTclC4jU/TNObC/xKZg==", + "@rollup/rollup-win32-x64-msvc@4.50.2": { + "integrity": "sha512-APwKy6YUhvZaEoHyM+9xqmTpviEI+9eL7LoCH+aLcvWYHJ663qG5zx7WzWZY+a9qkg5JtzcMyJ9z0WtQBMDmgA==", "os": ["win32"], "cpu": ["x64"] }, - "@tailwindcss/node@4.1.12": { - "integrity": "sha512-3hm9brwvQkZFe++SBt+oLjo4OLDtkvlE8q2WalaD/7QWaeM7KEJbAiY/LJZUaCs7Xa8aUu4xy3uoyX4q54UVdQ==", + "@tailwindcss/node@4.1.13": { + "integrity": "sha512-eq3ouolC1oEFOAvOMOBAmfCIqZBJuvWvvYWh5h5iOYfe1HFC6+GZ6EIL0JdM3/niGRJmnrOc+8gl9/HGUaaptw==", "dependencies": [ "@jridgewell/remapping", "enhanced-resolve", @@ -732,75 +780,67 @@ "tailwindcss" ] }, - "@tailwindcss/oxide-android-arm64@4.1.12": { - "integrity": "sha512-oNY5pq+1gc4T6QVTsZKwZaGpBb2N1H1fsc1GD4o7yinFySqIuRZ2E4NvGasWc6PhYJwGK2+5YT1f9Tp80zUQZQ==", + "@tailwindcss/oxide-android-arm64@4.1.13": { + "integrity": "sha512-BrpTrVYyejbgGo57yc8ieE+D6VT9GOgnNdmh5Sac6+t0m+v+sKQevpFVpwX3pBrM2qKrQwJ0c5eDbtjouY/+ew==", "os": ["android"], "cpu": ["arm64"] }, - "@tailwindcss/oxide-darwin-arm64@4.1.12": { - "integrity": "sha512-cq1qmq2HEtDV9HvZlTtrj671mCdGB93bVY6J29mwCyaMYCP/JaUBXxrQQQm7Qn33AXXASPUb2HFZlWiiHWFytw==", + "@tailwindcss/oxide-darwin-arm64@4.1.13": { + "integrity": "sha512-YP+Jksc4U0KHcu76UhRDHq9bx4qtBftp9ShK/7UGfq0wpaP96YVnnjFnj3ZFrUAjc5iECzODl/Ts0AN7ZPOANQ==", "os": ["darwin"], "cpu": ["arm64"] }, - "@tailwindcss/oxide-darwin-x64@4.1.12": { - "integrity": "sha512-6UCsIeFUcBfpangqlXay9Ffty9XhFH1QuUFn0WV83W8lGdX8cD5/+2ONLluALJD5+yJ7k8mVtwy3zMZmzEfbLg==", + "@tailwindcss/oxide-darwin-x64@4.1.13": { + "integrity": "sha512-aAJ3bbwrn/PQHDxCto9sxwQfT30PzyYJFG0u/BWZGeVXi5Hx6uuUOQEI2Fa43qvmUjTRQNZnGqe9t0Zntexeuw==", "os": ["darwin"], "cpu": ["x64"] }, - "@tailwindcss/oxide-freebsd-x64@4.1.12": { - "integrity": "sha512-JOH/f7j6+nYXIrHobRYCtoArJdMJh5zy5lr0FV0Qu47MID/vqJAY3r/OElPzx1C/wdT1uS7cPq+xdYYelny1ww==", + "@tailwindcss/oxide-freebsd-x64@4.1.13": { + "integrity": "sha512-Wt8KvASHwSXhKE/dJLCCWcTSVmBj3xhVhp/aF3RpAhGeZ3sVo7+NTfgiN8Vey/Fi8prRClDs6/f0KXPDTZE6nQ==", "os": ["freebsd"], "cpu": ["x64"] }, - "@tailwindcss/oxide-linux-arm-gnueabihf@4.1.12": { - "integrity": "sha512-v4Ghvi9AU1SYgGr3/j38PD8PEe6bRfTnNSUE3YCMIRrrNigCFtHZ2TCm8142X8fcSqHBZBceDx+JlFJEfNg5zQ==", + "@tailwindcss/oxide-linux-arm-gnueabihf@4.1.13": { + "integrity": "sha512-mbVbcAsW3Gkm2MGwA93eLtWrwajz91aXZCNSkGTx/R5eb6KpKD5q8Ueckkh9YNboU8RH7jiv+ol/I7ZyQ9H7Bw==", "os": ["linux"], "cpu": ["arm"] }, - "@tailwindcss/oxide-linux-arm64-gnu@4.1.12": { - "integrity": "sha512-YP5s1LmetL9UsvVAKusHSyPlzSRqYyRB0f+Kl/xcYQSPLEw/BvGfxzbH+ihUciePDjiXwHh+p+qbSP3SlJw+6g==", + "@tailwindcss/oxide-linux-arm64-gnu@4.1.13": { + "integrity": "sha512-wdtfkmpXiwej/yoAkrCP2DNzRXCALq9NVLgLELgLim1QpSfhQM5+ZxQQF8fkOiEpuNoKLp4nKZ6RC4kmeFH0HQ==", "os": ["linux"], "cpu": ["arm64"] }, - "@tailwindcss/oxide-linux-arm64-musl@4.1.12": { - "integrity": "sha512-V8pAM3s8gsrXcCv6kCHSuwyb/gPsd863iT+v1PGXC4fSL/OJqsKhfK//v8P+w9ThKIoqNbEnsZqNy+WDnwQqCA==", + "@tailwindcss/oxide-linux-arm64-musl@4.1.13": { + "integrity": "sha512-hZQrmtLdhyqzXHB7mkXfq0IYbxegaqTmfa1p9MBj72WPoDD3oNOh1Lnxf6xZLY9C3OV6qiCYkO1i/LrzEdW2mg==", "os": ["linux"], "cpu": ["arm64"] }, - "@tailwindcss/oxide-linux-x64-gnu@4.1.12": { - "integrity": "sha512-xYfqYLjvm2UQ3TZggTGrwxjYaLB62b1Wiysw/YE3Yqbh86sOMoTn0feF98PonP7LtjsWOWcXEbGqDL7zv0uW8Q==", + "@tailwindcss/oxide-linux-x64-gnu@4.1.13": { + "integrity": "sha512-uaZTYWxSXyMWDJZNY1Ul7XkJTCBRFZ5Fo6wtjrgBKzZLoJNrG+WderJwAjPzuNZOnmdrVg260DKwXCFtJ/hWRQ==", "os": ["linux"], "cpu": ["x64"] }, - "@tailwindcss/oxide-linux-x64-musl@4.1.12": { - "integrity": "sha512-ha0pHPamN+fWZY7GCzz5rKunlv9L5R8kdh+YNvP5awe3LtuXb5nRi/H27GeL2U+TdhDOptU7T6Is7mdwh5Ar3A==", + "@tailwindcss/oxide-linux-x64-musl@4.1.13": { + "integrity": "sha512-oXiPj5mi4Hdn50v5RdnuuIms0PVPI/EG4fxAfFiIKQh5TgQgX7oSuDWntHW7WNIi/yVLAiS+CRGW4RkoGSSgVQ==", "os": ["linux"], "cpu": ["x64"] }, - "@tailwindcss/oxide-wasm32-wasi@4.1.12": { - "integrity": "sha512-4tSyu3dW+ktzdEpuk6g49KdEangu3eCYoqPhWNsZgUhyegEda3M9rG0/j1GV/JjVVsj+lG7jWAyrTlLzd/WEBg==", - "dependencies": [ - "@emnapi/core", - "@emnapi/runtime", - "@emnapi/wasi-threads", - "@napi-rs/wasm-runtime", - "@tybys/wasm-util", - "tslib" - ], + "@tailwindcss/oxide-wasm32-wasi@4.1.13": { + "integrity": "sha512-+LC2nNtPovtrDwBc/nqnIKYh/W2+R69FA0hgoeOn64BdCX522u19ryLh3Vf3F8W49XBcMIxSe665kwy21FkhvA==", "cpu": ["wasm32"] }, - "@tailwindcss/oxide-win32-arm64-msvc@4.1.12": { - "integrity": "sha512-iGLyD/cVP724+FGtMWslhcFyg4xyYyM+5F4hGvKA7eifPkXHRAUDFaimu53fpNg9X8dfP75pXx/zFt/jlNF+lg==", + "@tailwindcss/oxide-win32-arm64-msvc@4.1.13": { + "integrity": "sha512-dziTNeQXtoQ2KBXmrjCxsuPk3F3CQ/yb7ZNZNA+UkNTeiTGgfeh+gH5Pi7mRncVgcPD2xgHvkFCh/MhZWSgyQg==", "os": ["win32"], "cpu": ["arm64"] }, - "@tailwindcss/oxide-win32-x64-msvc@4.1.12": { - "integrity": "sha512-NKIh5rzw6CpEodv/++r0hGLlfgT/gFN+5WNdZtvh6wpU2BpGNgdjvj6H2oFc8nCM839QM1YOhjpgbAONUb4IxA==", + "@tailwindcss/oxide-win32-x64-msvc@4.1.13": { + "integrity": "sha512-3+LKesjXydTkHk5zXX01b5KMzLV1xl2mcktBJkje7rhFUpUlYJy7IMOLqjIRQncLTa1WZZiFY/foAeB5nmaiTw==", "os": ["win32"], "cpu": ["x64"] }, - "@tailwindcss/oxide@4.1.12": { - "integrity": "sha512-gM5EoKHW/ukmlEtphNwaGx45fGoEmP10v51t9unv55voWh6WrOL19hfuIdo2FjxIaZzw776/BUQg7Pck++cIVw==", + "@tailwindcss/oxide@4.1.13": { + "integrity": "sha512-CPgsM1IpGRa880sMbYmG1s4xhAy3xEt1QULgTJGQmZUeNgXFR7s1YxYygmJyBGtou4SyEosGAGEeYqY7R53bIA==", "dependencies": [ "detect-libc", "tar" @@ -821,39 +861,39 @@ ], "scripts": true }, - "@tailwindcss/vite@4.1.12_vite@7.1.2__picomatch@4.0.3": { - "integrity": "sha512-4pt0AMFDx7gzIrAOIYgYP0KCBuKWqyW8ayrdiLEjoJTT4pKTjrzG/e4uzWtTLDziC+66R9wbUqZBccJalSE5vQ==", + "@tailwindcss/vite@4.1.13_vite@7.1.6__picomatch@4.0.3": { + "integrity": "sha512-0PmqLQ010N58SbMTJ7BVJ4I2xopiQn/5i6nlb4JmxzQf8zcS5+m2Cv6tqh+sfDwtIdjoEnOvwsGQ1hkUi8QEHQ==", "dependencies": [ "@tailwindcss/node", "@tailwindcss/oxide", "tailwindcss", - "vite@7.1.2_picomatch@4.0.3" + "vite@7.1.6_picomatch@4.0.3" ] }, - "@tailwindcss/vite@4.1.12_vite@7.1.2__picomatch@4.0.3_@types+node@22.15.15": { - "integrity": "sha512-4pt0AMFDx7gzIrAOIYgYP0KCBuKWqyW8ayrdiLEjoJTT4pKTjrzG/e4uzWtTLDziC+66R9wbUqZBccJalSE5vQ==", + "@tailwindcss/vite@4.1.13_vite@7.1.6__picomatch@4.0.3_@types+node@24.2.0": { + "integrity": "sha512-0PmqLQ010N58SbMTJ7BVJ4I2xopiQn/5i6nlb4JmxzQf8zcS5+m2Cv6tqh+sfDwtIdjoEnOvwsGQ1hkUi8QEHQ==", "dependencies": [ "@tailwindcss/node", "@tailwindcss/oxide", "tailwindcss", - "vite@7.1.2_picomatch@4.0.3_@types+node@22.15.15" + "vite@7.1.6_picomatch@4.0.3_@types+node@24.2.0" ] }, "@tanstack/history@1.131.2": { "integrity": "sha512-cs1WKawpXIe+vSTeiZUuSBy8JFjEuDgdMKZFRLKwQysKo8y2q6Q1HvS74Yw+m5IhOW1nTZooa6rlgdfXcgFAaw==" }, - "@tanstack/query-core@5.85.3": { - "integrity": "sha512-9Ne4USX83nHmRuEYs78LW+3lFEEO2hBDHu7mrdIgAFx5Zcrs7ker3n/i8p4kf6OgKExmaDN5oR0efRD7i2J0DQ==" + "@tanstack/query-core@5.89.0": { + "integrity": "sha512-joFV1MuPhSLsKfTzwjmPDrp8ENfZ9N23ymFu07nLfn3JCkSHy0CFgsyhHTJOmWaumC/WiNIKM0EJyduCF/Ih/Q==" }, - "@tanstack/react-query@5.85.3_react@19.1.1": { - "integrity": "sha512-AqU8TvNh5GVIE8I+TUU0noryBRy7gOY0XhSayVXmOPll4UkZeLWKDwi0rtWOZbwLRCbyxorfJ5DIjDqE7GXpcQ==", + "@tanstack/react-query@5.89.0_react@19.1.1": { + "integrity": "sha512-SXbtWSTSRXyBOe80mszPxpEbaN4XPRUp/i0EfQK1uyj3KCk/c8FuPJNIRwzOVe/OU3rzxrYtiNabsAmk1l714A==", "dependencies": [ "@tanstack/query-core", "react" ] }, - "@tanstack/react-router-devtools@1.131.18_@tanstack+react-router@1.131.18__react@19.1.1__react-dom@19.1.1___react@19.1.1_react@19.1.1_react-dom@19.1.1__react@19.1.1": { - "integrity": "sha512-arzMC4CexfTtBo2U8O2SbXl1lWKakd0JaYZJIFWJLQurKTYgvcHib9E9kExEtOHWBOkCFd0A22nGf7o1kn9YTg==", + "@tanstack/react-router-devtools@1.131.47_@tanstack+react-router@1.131.47__react@19.1.1__react-dom@19.1.1___react@19.1.1_react@19.1.1_react-dom@19.1.1__react@19.1.1": { + "integrity": "sha512-lbDUXLvShxC0cjIjzAAUtd+VzLPDJfiEAACykvGnW5dywBD/w20z7Hd8Jx8l/LrYOCI+EY8C6+0UxlnVqF5bdQ==", "dependencies": [ "@tanstack/react-router", "@tanstack/router-devtools-core", @@ -861,8 +901,8 @@ "react-dom" ] }, - "@tanstack/react-router@1.131.18_react@19.1.1_react-dom@19.1.1__react@19.1.1": { - "integrity": "sha512-8nNBajnkMrQQ46w4W1Tes4939zTPw0+CEpgR63DZmLVl+P0KPFJ1ogCxEiT5ZTUtJ1MXBlTl0QcO0qdQYfdHoA==", + "@tanstack/react-router@1.131.47_react@19.1.1_react-dom@19.1.1__react@19.1.1": { + "integrity": "sha512-yS5rUPjCvWRg+CZRnY7irKiNZEhLeIsNlwuhIdnIX2K7jU9gOc7pOIT8JI2Vo6IAhh/Mr+7aILKLPYxwTRnS5A==", "dependencies": [ "@tanstack/history", "@tanstack/react-store", @@ -874,8 +914,8 @@ "tiny-warning" ] }, - "@tanstack/react-store@0.7.3_react@19.1.1_react-dom@19.1.1__react@19.1.1": { - "integrity": "sha512-3Dnqtbw9P2P0gw8uUM8WP2fFfg8XMDSZCTsywRPZe/XqqYW8PGkXKZTvP0AHkE4mpqP9Y43GpOg9vwO44azu6Q==", + "@tanstack/react-store@0.7.5_react@19.1.1_react-dom@19.1.1__react@19.1.1": { + "integrity": "sha512-A+WZtEnHZpvbKXm8qR+xndNKywBLez2KKKKEQc7w0Qs45GvY1LpRI3BTZNmELwEVim8+Apf99iEDH2J+MUIzlQ==", "dependencies": [ "@tanstack/store", "react", @@ -883,8 +923,8 @@ "use-sync-external-store" ] }, - "@tanstack/router-core@1.131.18_seroval@1.3.2": { - "integrity": "sha512-zy+fonmDu0LWwojF3s2uaHk8JvOhIp4T0oJq4nouRfHuUHQu4D7myJ9piFPKYVUOqaVmfhhf3RB2Nq7kMzbpMQ==", + "@tanstack/router-core@1.131.47_seroval@1.3.2": { + "integrity": "sha512-ixwowt//SLvnuMoInSxSNCJ41J3S53FLgw8tu5MyXftZ9d7cVOnHoAuSOhKNJNyBDTC2JODC3w/4EH3KDMj6ew==", "dependencies": [ "@tanstack/history", "@tanstack/store", @@ -895,8 +935,8 @@ "tiny-warning" ] }, - "@tanstack/router-devtools-core@1.131.18_@tanstack+router-core@1.131.18__seroval@1.3.2_solid-js@1.9.9__seroval@1.3.2_tiny-invariant@1.3.3": { - "integrity": "sha512-ezlFrFI+LGC+lMfutemodqrJMpVsV2xsqgOk4A1sVeJ/inKymmglNzgEyZSm5Up7U+T8l24y/afqoQHpuaw+Bw==", + "@tanstack/router-devtools-core@1.131.47_@tanstack+router-core@1.131.47__seroval@1.3.2_solid-js@1.9.9__seroval@1.3.2_tiny-invariant@1.3.3": { + "integrity": "sha512-XKeTfZcy5RmlPUUYkidIeK/KIfjSWo1cFp0P9L+LleclbVa6pkIfjocSHqUiHM5wGlxkbC5EzZfLBqs2xTinuA==", "dependencies": [ "@tanstack/router-core", "clsx", @@ -905,14 +945,8 @@ "tiny-invariant" ] }, - "@tanstack/store@0.7.2": { - "integrity": "sha512-RP80Z30BYiPX2Pyo0Nyw4s1SJFH2jyM6f9i3HfX4pA+gm5jsnYryscdq2aIQLnL4TaGuQMO+zXmN9nh1Qck+Pg==" - }, - "@tybys/wasm-util@0.10.0": { - "integrity": "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==", - "dependencies": [ - "tslib" - ] + "@tanstack/store@0.7.5": { + "integrity": "sha512-qd/OjkjaFRKqKU4Yjipaen/EOB9MyEg6Wr9fW103RBPACf1ZcKhbhcu2S5mj5IgdPib6xFIgCUti/mKVkl+fRw==" }, "@types/babel__core@7.20.5": { "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", @@ -949,20 +983,20 @@ "@types/json-schema@7.0.15": { "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" }, - "@types/node@22.15.15": { - "integrity": "sha512-R5muMcZob3/Jjchn5LcO8jdKwSCbzqmPB6ruBxMcf9kbxtniZHP327s6C37iOfuw8mbKK3cAQa7sEl7afLrQ8A==", + "@types/node@24.2.0": { + "integrity": "sha512-3xyG3pMCq3oYCNg7/ZP+E1ooTaGB4cG8JWRsqqOYQdbWNY4zbaV0Ennrd7stjiJEFZCaybcIgpTjJWHRfBSIDw==", "dependencies": [ "undici-types" ] }, - "@types/react-dom@19.1.7_@types+react@19.1.10": { - "integrity": "sha512-i5ZzwYpqjmrKenzkoLM2Ibzt6mAsM7pxB6BCIouEVVmgiqaMj1TjaK7hnA36hbW5aZv20kx7Lw6hWzPWg0Rurw==", + "@types/react-dom@19.1.9_@types+react@19.1.13": { + "integrity": "sha512-qXRuZaOsAdXKFyOhRBg6Lqqc0yay13vN7KrIg4L7N4aaHN68ma9OK3NE1BoDFgFOTfM7zg+3/8+2n8rLUH3OKQ==", "dependencies": [ "@types/react" ] }, - "@types/react@19.1.10": { - "integrity": "sha512-EhBeSYX0Y6ye8pNebpKrwFJq7BoQ8J5SO6NlvNwwHjSj6adXJViPQrKlsyPw7hLBLvckEMO1yxeGdR82YBBlDg==", + "@types/react@19.1.13": { + "integrity": "sha512-hHkbU/eoO3EG5/MZkuFSKmYqPbSVk5byPFa3e7y/8TybHiLMACgI8seVYlicwk7H5K/rI2px9xrQp/C+AUDTiQ==", "dependencies": [ "csstype" ] @@ -976,8 +1010,8 @@ "@types/webidl-conversions" ] }, - "@typescript-eslint/eslint-plugin@8.39.1_@typescript-eslint+parser@8.39.1__eslint@9.33.0__typescript@5.9.2_eslint@9.33.0_typescript@5.9.2": { - "integrity": "sha512-yYegZ5n3Yr6eOcqgj2nJH8cH/ZZgF+l0YIdKILSDjYFRjgYQMgv/lRjV5Z7Up04b9VYUondt8EPMqg7kTWgJ2g==", + "@typescript-eslint/eslint-plugin@8.44.0_@typescript-eslint+parser@8.44.0__eslint@9.35.0__typescript@5.9.2_eslint@9.35.0_typescript@5.9.2": { + "integrity": "sha512-EGDAOGX+uwwekcS0iyxVDmRV9HX6FLSM5kzrAToLTsr9OWCIKG/y3lQheCq18yZ5Xh78rRKJiEpP0ZaCs4ryOQ==", "dependencies": [ "@eslint-community/regexpp", "@typescript-eslint/parser", @@ -993,8 +1027,8 @@ "typescript" ] }, - "@typescript-eslint/parser@8.39.1_eslint@9.33.0_typescript@5.9.2": { - "integrity": "sha512-pUXGCuHnnKw6PyYq93lLRiZm3vjuslIy7tus1lIQTYVK9bL8XBgJnCWm8a0KcTtHC84Yya1Q6rtll+duSMj0dg==", + "@typescript-eslint/parser@8.44.0_eslint@9.35.0_typescript@5.9.2": { + "integrity": "sha512-VGMpFQGUQWYT9LfnPcX8ouFojyrZ/2w3K5BucvxL/spdNehccKhB4jUyB1yBCXpr2XFm0jkECxgrpXBW2ipoAw==", "dependencies": [ "@typescript-eslint/scope-manager", "@typescript-eslint/types", @@ -1005,8 +1039,8 @@ "typescript" ] }, - "@typescript-eslint/project-service@8.39.1_typescript@5.9.2": { - "integrity": "sha512-8fZxek3ONTwBu9ptw5nCKqZOSkXshZB7uAxuFF0J/wTMkKydjXCzqqga7MlFMpHi9DoG4BadhmTkITBcg8Aybw==", + "@typescript-eslint/project-service@8.44.0_typescript@5.9.2": { + "integrity": "sha512-ZeaGNraRsq10GuEohKTo4295Z/SuGcSq2LzfGlqiuEvfArzo/VRrT0ZaJsVPuKZ55lVbNk8U6FcL+ZMH8CoyVA==", "dependencies": [ "@typescript-eslint/tsconfig-utils", "@typescript-eslint/types", @@ -1014,21 +1048,21 @@ "typescript" ] }, - "@typescript-eslint/scope-manager@8.39.1": { - "integrity": "sha512-RkBKGBrjgskFGWuyUGz/EtD8AF/GW49S21J8dvMzpJitOF1slLEbbHnNEtAHtnDAnx8qDEdRrULRnWVx27wGBw==", + "@typescript-eslint/scope-manager@8.44.0": { + "integrity": "sha512-87Jv3E+al8wpD+rIdVJm/ItDBe/Im09zXIjFoipOjr5gHUhJmTzfFLuTJ/nPTMc2Srsroy4IBXwcTCHyRR7KzA==", "dependencies": [ "@typescript-eslint/types", "@typescript-eslint/visitor-keys" ] }, - "@typescript-eslint/tsconfig-utils@8.39.1_typescript@5.9.2": { - "integrity": "sha512-ePUPGVtTMR8XMU2Hee8kD0Pu4NDE1CN9Q1sxGSGd/mbOtGZDM7pnhXNJnzW63zk/q+Z54zVzj44HtwXln5CvHA==", + "@typescript-eslint/tsconfig-utils@8.44.0_typescript@5.9.2": { + "integrity": "sha512-x5Y0+AuEPqAInc6yd0n5DAcvtoQ/vyaGwuX5HE9n6qAefk1GaedqrLQF8kQGylLUb9pnZyLf+iEiL9fr8APDtQ==", "dependencies": [ "typescript" ] }, - "@typescript-eslint/type-utils@8.39.1_eslint@9.33.0_typescript@5.9.2": { - "integrity": "sha512-gu9/ahyatyAdQbKeHnhT4R+y3YLtqqHyvkfDxaBYk97EcbfChSJXyaJnIL3ygUv7OuZatePHmQvuH5ru0lnVeA==", + "@typescript-eslint/type-utils@8.44.0_eslint@9.35.0_typescript@5.9.2": { + "integrity": "sha512-9cwsoSxJ8Sak67Be/hD2RNt/fsqmWnNE1iHohG8lxqLSNY8xNfyY7wloo5zpW3Nu9hxVgURevqfcH6vvKCt6yg==", "dependencies": [ "@typescript-eslint/types", "@typescript-eslint/typescript-estree", @@ -1039,11 +1073,11 @@ "typescript" ] }, - "@typescript-eslint/types@8.39.1": { - "integrity": "sha512-7sPDKQQp+S11laqTrhHqeAbsCfMkwJMrV7oTDvtDds4mEofJYir414bYKUEb8YPUm9QL3U+8f6L6YExSoAGdQw==" + "@typescript-eslint/types@8.44.0": { + "integrity": "sha512-ZSl2efn44VsYM0MfDQe68RKzBz75NPgLQXuGypmym6QVOWL5kegTZuZ02xRAT9T+onqvM6T8CdQk0OwYMB6ZvA==" }, - "@typescript-eslint/typescript-estree@8.39.1_typescript@5.9.2": { - "integrity": "sha512-EKkpcPuIux48dddVDXyQBlKdeTPMmALqBUbEk38McWv0qVEZwOpVJBi7ugK5qVNgeuYjGNQxrrnoM/5+TI/BPw==", + "@typescript-eslint/typescript-estree@8.44.0_typescript@5.9.2": { + "integrity": "sha512-lqNj6SgnGcQZwL4/SBJ3xdPEfcBuhCG8zdcwCPgYcmiPLgokiNDKlbPzCwEwu7m279J/lBYWtDYL+87OEfn8Jw==", "dependencies": [ "@typescript-eslint/project-service", "@typescript-eslint/tsconfig-utils", @@ -1058,8 +1092,8 @@ "typescript" ] }, - "@typescript-eslint/utils@8.39.1_eslint@9.33.0_typescript@5.9.2": { - "integrity": "sha512-VF5tZ2XnUSTuiqZFXCZfZs1cgkdd3O/sSYmdo2EpSyDlC86UM/8YytTmKnehOW3TGAlivqTDT6bS87B/GQ/jyg==", + "@typescript-eslint/utils@8.44.0_eslint@9.35.0_typescript@5.9.2": { + "integrity": "sha512-nktOlVcg3ALo0mYlV+L7sWUD58KG4CMj1rb2HUVOO4aL3K/6wcD+NERqd0rrA5Vg06b42YhF6cFxeixsp9Riqg==", "dependencies": [ "@eslint-community/eslint-utils", "@typescript-eslint/scope-manager", @@ -1069,26 +1103,14 @@ "typescript" ] }, - "@typescript-eslint/visitor-keys@8.39.1": { - "integrity": "sha512-W8FQi6kEh2e8zVhQ0eeRnxdvIoOkAp/CPAahcNio6nO9dsIwb9b34z90KOlheoyuVf6LSOEdjlkxSkapNEc+4A==", + "@typescript-eslint/visitor-keys@8.44.0": { + "integrity": "sha512-zaz9u8EJ4GBmnehlrpoKvj/E3dNbuQ7q0ucyZImm3cLqJ8INTc970B1qEqDX/Rzq65r3TvVTN7kHWPBoyW7DWw==", "dependencies": [ "@typescript-eslint/types", "eslint-visitor-keys@4.2.1" ] }, - "@valkyr/db@1.0.1": { - "integrity": "sha512-zOvf0jbTSOtjzAgWKeD6S3/QQdtodPy+LkxfnhoggOzYhthkmZ1A8SauucFgkvIrzEp8e3IfNBHy0qQUHJRTog==", - "dependencies": [ - "dot-prop", - "fast-equals@5.0.1", - "idb@7.1.1", - "mingo@6.4.6", - "nanoid@5.0.2", - "rfdc", - "rxjs@7.8.1" - ] - }, - "@vitejs/plugin-react@4.7.0_vite@7.1.2__picomatch@4.0.3_@babel+core@7.28.3": { + "@vitejs/plugin-react@4.7.0_vite@7.1.6__picomatch@4.0.3_@babel+core@7.28.4": { "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", "dependencies": [ "@babel/core", @@ -1097,10 +1119,10 @@ "@rolldown/pluginutils", "@types/babel__core", "react-refresh", - "vite@7.1.2_picomatch@4.0.3" + "vite@7.1.6_picomatch@4.0.3" ] }, - "@vitejs/plugin-react@4.7.0_vite@7.1.2__picomatch@4.0.3_@babel+core@7.28.3_@types+node@22.15.15": { + "@vitejs/plugin-react@4.7.0_vite@7.1.6__picomatch@4.0.3_@babel+core@7.28.4_@types+node@24.2.0": { "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", "dependencies": [ "@babel/core", @@ -1109,7 +1131,7 @@ "@rolldown/pluginutils", "@types/babel__core", "react-refresh", - "vite@7.1.2_picomatch@4.0.3_@types+node@22.15.15" + "vite@7.1.6_picomatch@4.0.3_@types+node@24.2.0" ] }, "acorn-jsx@5.3.2_acorn@8.15.0": { @@ -1131,6 +1153,9 @@ "uri-js" ] }, + "ansi-regex@5.0.1": { + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, "ansi-styles@4.3.0": { "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": [ @@ -1143,6 +1168,10 @@ "balanced-match@1.0.2": { "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "baseline-browser-mapping@2.8.6": { + "integrity": "sha512-wrH5NNqren/QMtKUEEJf7z86YjfqW/2uw3IL3/xpqZUC95SSVIFXYQeeGjL6FT/X68IROu6RMehZQS5foy2BXw==", + "bin": true + }, "brace-expansion@1.1.12": { "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dependencies": [ @@ -1162,9 +1191,10 @@ "fill-range" ] }, - "browserslist@4.25.2": { - "integrity": "sha512-0si2SJK3ooGzIawRu61ZdPCO1IncZwS8IzuX73sPZsXW6EQ/w/DAfPyKI8l1ETTCr2MnvqWitmlCUxgdul45jA==", + "browserslist@4.26.2": { + "integrity": "sha512-ECFzp6uFOSB+dcZ5BK/IBaGWssbSYBHvuMeMt3MMFyhI0Z8SqGgEkBLARgpRH3hutIgPVsALcMwbDrJqPxQ65A==", "dependencies": [ + "baseline-browser-mapping", "caniuse-lite", "electron-to-chromium", "node-releases", @@ -1175,11 +1205,25 @@ "bson@6.10.4": { "integrity": "sha512-WIsKqkSC0ABoBJuT1LEX+2HEvNmNKKgnTAyd0fL8qzK4SH2i9NXg+t08YtdZp/V9IZ33cxe3iV4yM0qg8lMQng==" }, + "call-bind-apply-helpers@1.0.2": { + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dependencies": [ + "es-errors", + "function-bind" + ] + }, + "call-bound@1.0.4": { + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dependencies": [ + "call-bind-apply-helpers", + "get-intrinsic" + ] + }, "callsites@3.1.0": { "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" }, - "caniuse-lite@1.0.30001735": { - "integrity": "sha512-EV/laoX7Wq2J9TQlyIXRxTJqIw4sxfXS4OYgudGxBYRuTv0q7AM6yMEpU/Vo1I94thg9U6EZ2NfZx9GJq83u7w==" + "caniuse-lite@1.0.30001743": { + "integrity": "sha512-e6Ojr7RV14Un7dz6ASD0aZDmQPT/A+eZU+nuTNfjqmRrmkmQlnTNWH0SKmqagx9PeW87UVqapSurtAXifmtdmw==" }, "chalk@4.1.2": { "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", @@ -1191,6 +1235,14 @@ "chownr@3.0.0": { "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==" }, + "cliui@8.0.1": { + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dependencies": [ + "string-width", + "strip-ansi", + "wrap-ansi" + ] + }, "clsx@2.1.1": { "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==" }, @@ -1226,8 +1278,8 @@ "csstype@3.1.3": { "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, - "debug@4.4.1": { - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "debug@4.4.3": { + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dependencies": [ "ms" ] @@ -1235,17 +1287,22 @@ "deep-is@0.1.4": { "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" }, - "detect-libc@2.0.4": { - "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==" + "detect-libc@2.1.0": { + "integrity": "sha512-vEtk+OcP7VBRtQZ1EJ3bdgzSfBjgnEalLTp5zjJrS+2Z1w2KZly4SBdac/WDU3hhsNAZ9E8SC96ME4Ey8MZ7cg==" }, - "dot-prop@8.0.2": { - "integrity": "sha512-xaBe6ZT4DHPkg0k4Ytbvn5xoxgpG0jOS1dYxSOwAHPuNLjP3/OzN0gH55SrLqpx8cBfSaVt91lXYkApjb+nYdQ==", + "dunder-proto@1.0.1": { + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "dependencies": [ - "type-fest" + "call-bind-apply-helpers", + "es-errors", + "gopd" ] }, - "electron-to-chromium@1.5.203": { - "integrity": "sha512-uz4i0vLhfm6dLZWbz/iH88KNDV+ivj5+2SA+utpgjKaj9Q0iDLuwk6Idhe9BTxciHudyx6IvTvijhkPvFGUQ0g==" + "electron-to-chromium@1.5.222": { + "integrity": "sha512-gA7psSwSwQRE60CEoLz6JBCQPIxNeuzB2nL8vE03GK/OHxlvykbLyeiumQy1iH5C2f3YbRAZpGCMT12a/9ih9w==" + }, + "emoji-regex@8.0.0": { + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "enhanced-resolve@5.18.3": { "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", @@ -1254,8 +1311,20 @@ "tapable" ] }, - "esbuild@0.25.9": { - "integrity": "sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==", + "es-define-property@1.0.1": { + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==" + }, + "es-errors@1.3.0": { + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" + }, + "es-object-atoms@1.1.1": { + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dependencies": [ + "es-errors" + ] + }, + "esbuild@0.25.10": { + "integrity": "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==", "optionalDependencies": [ "@esbuild/aix-ppc64", "@esbuild/android-arm", @@ -1293,19 +1362,19 @@ "escape-string-regexp@4.0.0": { "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" }, - "eslint-plugin-react-hooks@5.2.0_eslint@9.33.0": { + "eslint-plugin-react-hooks@5.2.0_eslint@9.35.0": { "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==", "dependencies": [ "eslint" ] }, - "eslint-plugin-react-refresh@0.4.20_eslint@9.33.0": { + "eslint-plugin-react-refresh@0.4.20_eslint@9.35.0": { "integrity": "sha512-XpbHQ2q5gUF8BGOX4dHe+71qoirYMhApEPZ7sfhF/dNnOF1UXnCMGZf79SFTBO7Bz5YEIT4TMieSlJBWhP9WBA==", "dependencies": [ "eslint" ] }, - "eslint-plugin-simple-import-sort@12.1.1_eslint@9.33.0": { + "eslint-plugin-simple-import-sort@12.1.1_eslint@9.35.0": { "integrity": "sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA==", "dependencies": [ "eslint" @@ -1324,8 +1393,8 @@ "eslint-visitor-keys@4.2.1": { "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==" }, - "eslint@9.33.0": { - "integrity": "sha512-TS9bTNIryDzStCpJN93aC5VRSW3uTx9sClUn4B87pwiCaJh220otoI0X8mJKr+VcPtniMdN8GKjlwgWGUv5ZKA==", + "eslint@9.35.0": { + "integrity": "sha512-QePbBFMJFjgmlE+cXAlbHZbHpdFVS2E/6vzCy7aKlebddvl1vadiC4JFV5u/wqTkNUwEV8WrQi257jf5f06hrg==", "dependencies": [ "@eslint-community/eslint-utils", "@eslint-community/regexpp", @@ -1337,7 +1406,7 @@ "@eslint/plugin-kit", "@humanfs/node", "@humanwhocodes/module-importer", - "@humanwhocodes/retry@0.4.3", + "@humanwhocodes/retry", "@types/estree", "@types/json-schema", "ajv", @@ -1397,9 +1466,6 @@ "fast-deep-equal@3.1.3": { "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, - "fast-equals@5.0.1": { - "integrity": "sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==" - }, "fast-equals@5.2.2": { "integrity": "sha512-V7/RktU11J3I36Nwq2JnZEM7tNm17eBJz+u25qdxBZeCKiX6BkVSZQjwWIr+IobgnZy+ag73tTZgZi7tr0LrBw==" }, @@ -1468,9 +1534,37 @@ "os": ["darwin"], "scripts": true }, + "function-bind@1.1.2": { + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, "gensync@1.0.0-beta.2": { "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" }, + "get-caller-file@2.0.5": { + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "get-intrinsic@1.3.0": { + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dependencies": [ + "call-bind-apply-helpers", + "es-define-property", + "es-errors", + "es-object-atoms", + "function-bind", + "get-proto", + "gopd", + "has-symbols", + "hasown", + "math-intrinsics" + ] + }, + "get-proto@1.0.1": { + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dependencies": [ + "dunder-proto", + "es-object-atoms" + ] + }, "glob-parent@5.1.2": { "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dependencies": [ @@ -1486,8 +1580,8 @@ "globals@14.0.0": { "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==" }, - "globals@16.3.0": { - "integrity": "sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ==" + "globals@16.4.0": { + "integrity": "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==" }, "goober@2.1.16_csstype@3.1.3": { "integrity": "sha512-erjk19y1U33+XAMe1VTvIONHYoSqE4iS7BYUZfHaqeohLmnC0FdxEh7rQU+6MZ4OajItzjZFSRtVANrQwNq6/g==", @@ -1495,6 +1589,9 @@ "csstype" ] }, + "gopd@1.2.0": { + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==" + }, "graceful-fs@4.2.11": { "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, @@ -1504,8 +1601,14 @@ "has-flag@4.0.0": { "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, - "idb@7.1.1": { - "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==" + "has-symbols@1.1.0": { + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==" + }, + "hasown@2.0.2": { + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": [ + "function-bind" + ] }, "idb@8.0.3": { "integrity": "sha512-LtwtVyVYO5BqRvcsKuB2iUMnHwPVByPCXFXOpuU96IZPPoPN6xjOGxZQ74pgSVVLQWtUOYgyeL4GE98BY5D3wg==" @@ -1529,6 +1632,9 @@ "is-extglob@2.1.1": { "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" }, + "is-fullwidth-code-point@3.0.0": { + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, "is-glob@4.0.3": { "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dependencies": [ @@ -1538,8 +1644,8 @@ "is-number@7.0.0": { "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, - "isbot@5.1.29": { - "integrity": "sha512-DelDWWoa3mBoyWTq3wjp+GIWx/yZdN7zLUE7NFhKjAiJ+uJVRkbLlwykdduCE4sPUUy8mlTYTmdhBUYu91F+sw==" + "isbot@5.1.30": { + "integrity": "sha512-3wVJEonAns1OETX83uWsk5IAne2S5zfDcntD2hbtU23LelSqNXzXs9zKjMPOLMzroCgIjCfjYAEHrd2D6FOkiA==" }, "isexe@2.0.0": { "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" @@ -1548,8 +1654,8 @@ "integrity": "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==", "bin": true }, - "jose@6.0.10": { - "integrity": "sha512-skIAxZqcMkOrSwjJvplIPYrlXGpxTPnro2/QWTDCxAdWQrSTV5/KqspMWmi5WAx5+ULswASJiZ0a+1B/Lxt9cw==" + "jose@6.1.0": { + "integrity": "sha512-TTQJyoEoKcC1lscpVDCSsVgYzUDg/0Bt3WE//WiTPK6uOCQC2KZS4MpugbMWt/zyjkopgZoXhZuCi00gLudfUA==" }, "js-tokens@4.0.0": { "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" @@ -1665,21 +1771,30 @@ "p-locate" ] }, + "lodash.camelcase@4.3.0": { + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" + }, "lodash.merge@4.6.2": { "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, + "long@5.3.2": { + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==" + }, "lru-cache@5.1.1": { "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dependencies": [ "yallist@3.1.1" ] }, - "magic-string@0.30.17": { - "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "magic-string@0.30.19": { + "integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==", "dependencies": [ "@jridgewell/sourcemap-codec" ] }, + "math-intrinsics@1.1.0": { + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==" + }, "memory-pager@1.5.0": { "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" }, @@ -1693,9 +1808,6 @@ "picomatch@2.3.1" ] }, - "mingo@6.4.6": { - "integrity": "sha512-SMp06Eo5iEthCPpKXgEZ6DTZKxknpTqj49YN6iHpapj9DKltBCv0RFu+0mBBjMU0SiHR9pYkurkk74+VFGTqxw==" - }, "mingo@6.6.1": { "integrity": "sha512-KC6b1ODYoSdYu5fBm+SzQb7fa4ARmGwfa3Cf9F7U+2mnfD4Zhf89qQgO1cPTtaJ68w3ntIT5dVujgF52HvN7+g==" }, @@ -1731,8 +1843,8 @@ "whatwg-url" ] }, - "mongodb@6.18.0": { - "integrity": "sha512-fO5ttN9VC8P0F5fqtQmclAkgXZxbIkYRTUi1j8JO6IYwvamkhtYDilJr35jOPELR49zqCJgXZWwCtW7B+TM8vQ==", + "mongodb@6.20.0": { + "integrity": "sha512-Tl6MEIU3K4Rq3TSHd+sZQqRBoGlFsOgNrH5ltAcFBV62Re3Fd+FcaVf8uSEQFOJ51SDowDVttBTONMfoYWrWlQ==", "dependencies": [ "@mongodb-js/saslprep", "bson", @@ -1746,15 +1858,14 @@ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "bin": true }, - "nanoid@5.0.2": { - "integrity": "sha512-2ustYUX1R2rL/Br5B/FMhi8d5/QzvkJ912rBYxskcpu0myTHzSZfTr1LAS2Sm7jxRUObRrSBFoyzwAhL49aVSg==", - "bin": true - }, "natural-compare@1.4.0": { "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" }, - "node-releases@2.0.19": { - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==" + "node-releases@2.0.21": { + "integrity": "sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw==" + }, + "object-inspect@1.13.4": { + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==" }, "optionator@0.9.4": { "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", @@ -1791,8 +1902,8 @@ "path-key@3.1.1": { "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" }, - "path-to-regexp@8.2.0": { - "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==" + "path-to-regexp@8.3.0": { + "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==" }, "picocolors@1.1.1": { "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" @@ -1806,7 +1917,7 @@ "postcss@8.5.6": { "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", "dependencies": [ - "nanoid@3.3.11", + "nanoid", "picocolors", "source-map-js" ] @@ -1821,9 +1932,33 @@ "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", "bin": true }, + "protobufjs@7.5.4": { + "integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==", + "dependencies": [ + "@protobufjs/aspromise", + "@protobufjs/base64", + "@protobufjs/codegen", + "@protobufjs/eventemitter", + "@protobufjs/fetch", + "@protobufjs/float", + "@protobufjs/inquire", + "@protobufjs/path", + "@protobufjs/pool", + "@protobufjs/utf8", + "@types/node", + "long" + ], + "scripts": true + }, "punycode@2.3.1": { "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==" }, + "qs@6.14.0": { + "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "dependencies": [ + "side-channel" + ] + }, "queue-microtask@1.2.3": { "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" }, @@ -1840,17 +1975,17 @@ "react@19.1.1": { "integrity": "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==" }, + "require-directory@2.1.1": { + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" + }, "resolve-from@4.0.0": { "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" }, "reusify@1.1.0": { "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==" }, - "rfdc@1.3.0": { - "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" - }, - "rollup@4.46.2": { - "integrity": "sha512-WMmLFI+Boh6xbop+OAGo9cQ3OgX9MIg7xOQjn+pTCwOkk+FNDAeAemXkJ3HzDJrVXleLOFVa1ipuc1AmEx1Dwg==", + "rollup@4.50.2": { + "integrity": "sha512-BgLRGy7tNS9H66aIMASq1qSYbAAJV6Z6WR4QYTvj5FgF15rZ/ympT1uixHXwzbZUBDbkvqUI1KR0fH1FhMaQ9w==", "dependencies": [ "@types/estree" ], @@ -1865,13 +2000,14 @@ "@rollup/rollup-linux-arm-musleabihf", "@rollup/rollup-linux-arm64-gnu", "@rollup/rollup-linux-arm64-musl", - "@rollup/rollup-linux-loongarch64-gnu", + "@rollup/rollup-linux-loong64-gnu", "@rollup/rollup-linux-ppc64-gnu", "@rollup/rollup-linux-riscv64-gnu", "@rollup/rollup-linux-riscv64-musl", "@rollup/rollup-linux-s390x-gnu", "@rollup/rollup-linux-x64-gnu", "@rollup/rollup-linux-x64-musl", + "@rollup/rollup-openharmony-arm64", "@rollup/rollup-win32-arm64-msvc", "@rollup/rollup-win32-ia32-msvc", "@rollup/rollup-win32-x64-msvc", @@ -1885,12 +2021,6 @@ "queue-microtask" ] }, - "rxjs@7.8.1": { - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "dependencies": [ - "tslib" - ] - }, "rxjs@7.8.2": { "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", "dependencies": [ @@ -1908,8 +2038,8 @@ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "bin": true }, - "seroval-plugins@1.3.2_seroval@1.3.2": { - "integrity": "sha512-0QvCV2lM3aj/U3YozDiVwx9zpH0q8A60CTWIv4Jszj/givcudPb48B+rkU5D51NJ0pTpweGMttHjboPa9/zoIQ==", + "seroval-plugins@1.3.3_seroval@1.3.2": { + "integrity": "sha512-16OL3NnUBw8JG1jBLUoZJsLnQq0n5Ua6aHalhJK4fMQkz1lqR7Osz1sA30trBtd9VUDc2NgkuRCn8+/pBwqZ+w==", "dependencies": [ "seroval" ] @@ -1926,6 +2056,42 @@ "shebang-regex@3.0.0": { "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" }, + "side-channel-list@1.0.0": { + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dependencies": [ + "es-errors", + "object-inspect" + ] + }, + "side-channel-map@1.0.1": { + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dependencies": [ + "call-bound", + "es-errors", + "get-intrinsic", + "object-inspect" + ] + }, + "side-channel-weakmap@1.0.2": { + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dependencies": [ + "call-bound", + "es-errors", + "get-intrinsic", + "object-inspect", + "side-channel-map" + ] + }, + "side-channel@1.1.0": { + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dependencies": [ + "es-errors", + "object-inspect", + "side-channel-list", + "side-channel-map", + "side-channel-weakmap" + ] + }, "solid-js@1.9.9_seroval@1.3.2": { "integrity": "sha512-A0ZBPJQldAeGCTW0YRYJmt7RCeh5rbFfPZ2aOttgYnctHE7HgKeHCBB/PVc2P7eOfmNXqMFFFoYYdm3S4dcbkA==", "dependencies": [ @@ -1943,6 +2109,20 @@ "memory-pager" ] }, + "string-width@4.2.3": { + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": [ + "emoji-regex", + "is-fullwidth-code-point", + "strip-ansi" + ] + }, + "strip-ansi@6.0.1": { + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": [ + "ansi-regex" + ] + }, "strip-json-comments@3.1.1": { "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" }, @@ -1952,11 +2132,11 @@ "has-flag" ] }, - "tailwindcss@4.1.12": { - "integrity": "sha512-DzFtxOi+7NsFf7DBtI3BJsynR+0Yp6etH+nRPTbpWnS2pZBaSksv/JGctNwSWzbFjp0vxSqknaUylseZqMDGrA==" + "tailwindcss@4.1.13": { + "integrity": "sha512-i+zidfmTqtwquj4hMEwdjshYYgMbOrPzb9a0M3ZgNa0JMoZeFC6bxZvO8yr8ozS6ix2SDz0+mvryPeBs2TFE+w==" }, - "tapable@2.2.2": { - "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==" + "tapable@2.2.3": { + "integrity": "sha512-ZL6DDuAlRlLGghwcfmSn9sK3Hr6ArtyudlSAiCqQ6IfE+b+HHbydbYDIG15IfS5do+7XQQBdBiubF/cV2dnDzg==" }, "tar@7.4.3": { "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", @@ -1975,8 +2155,8 @@ "tiny-warning@1.0.3": { "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" }, - "tinyglobby@0.2.14_picomatch@4.0.3": { - "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", + "tinyglobby@0.2.15_picomatch@4.0.3": { + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", "dependencies": [ "fdir", "picomatch@4.0.3" @@ -2009,11 +2189,8 @@ "prelude-ls" ] }, - "type-fest@3.13.1": { - "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==" - }, - "typescript-eslint@8.39.1_eslint@9.33.0_typescript@5.9.2_@typescript-eslint+parser@8.39.1__eslint@9.33.0__typescript@5.9.2": { - "integrity": "sha512-GDUv6/NDYngUlNvwaHM1RamYftxf782IyEDbdj3SeaIHHv8fNQVRC++fITT7kUJV/5rIA/tkoRSSskt6osEfqg==", + "typescript-eslint@8.44.0_eslint@9.35.0_typescript@5.9.2_@typescript-eslint+parser@8.44.0__eslint@9.35.0__typescript@5.9.2": { + "integrity": "sha512-ib7mCkYuIzYonCq9XWF5XNw+fkj2zg629PSa9KNIQ47RXFF763S5BIX4wqz1+FLPogTZoiw8KmCiRPRa8bL3qw==", "dependencies": [ "@typescript-eslint/eslint-plugin", "@typescript-eslint/parser", @@ -2027,10 +2204,10 @@ "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", "bin": true }, - "undici-types@6.21.0": { - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==" + "undici-types@7.10.0": { + "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==" }, - "update-browserslist-db@1.1.3_browserslist@4.25.2": { + "update-browserslist-db@1.1.3_browserslist@4.26.2": { "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", "dependencies": [ "browserslist", @@ -2051,8 +2228,12 @@ "react" ] }, - "vite@7.1.2_picomatch@4.0.3": { - "integrity": "sha512-J0SQBPlQiEXAF7tajiH+rUooJPo0l8KQgyg4/aMunNtrOa7bwuZJsJbDWzeljqQpgftxuq5yNJxQ91O9ts29UQ==", + "uuid@13.0.0": { + "integrity": "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==", + "bin": true + }, + "vite@7.1.6_picomatch@4.0.3": { + "integrity": "sha512-SRYIB8t/isTwNn8vMB3MR6E+EQZM/WG1aKmmIUCfDXfVvKfc20ZpamngWHKzAmmu9ppsgxsg4b2I7c90JZudIQ==", "dependencies": [ "esbuild", "fdir", @@ -2066,8 +2247,8 @@ ], "bin": true }, - "vite@7.1.2_picomatch@4.0.3_@types+node@22.15.15": { - "integrity": "sha512-J0SQBPlQiEXAF7tajiH+rUooJPo0l8KQgyg4/aMunNtrOa7bwuZJsJbDWzeljqQpgftxuq5yNJxQ91O9ts29UQ==", + "vite@7.1.6_picomatch@4.0.3_@types+node@24.2.0": { + "integrity": "sha512-SRYIB8t/isTwNn8vMB3MR6E+EQZM/WG1aKmmIUCfDXfVvKfc20ZpamngWHKzAmmu9ppsgxsg4b2I7c90JZudIQ==", "dependencies": [ "@types/node", "esbuild", @@ -2105,77 +2286,102 @@ "word-wrap@1.2.5": { "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==" }, + "wrap-ansi@7.0.0": { + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": [ + "ansi-styles", + "string-width", + "strip-ansi" + ] + }, + "y18n@5.0.8": { + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + }, "yallist@3.1.1": { "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "yallist@5.0.0": { "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==" }, + "yargs-parser@21.1.1": { + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" + }, + "yargs@17.7.2": { + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dependencies": [ + "cliui", + "escalade", + "get-caller-file", + "require-directory", + "string-width", + "y18n", + "yargs-parser" + ] + }, "yocto-queue@0.1.0": { "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" }, - "zod@3.25.0-beta.20250519T094321": { - "integrity": "sha512-FvDMTcBUhM/CZjeT0HJQ8M6KbSGRPHqEx2yLWx9kDU3ufoTiq7tQAI8UyBJ/82CBp1mv6tKVWp00ll6zV/WxmA==" - }, - "zod@4.0.17": { - "integrity": "sha512-1PHjlYRevNxxdy2JZ8JcNAw7rX8V9P1AKkP+x/xZfxB0K5FYfuV+Ug6P/6NVSR2jHQ+FzDDoDHS04nYUsOIyLQ==" + "zod@4.1.9": { + "integrity": "sha512-HI32jTq0AUAC125z30E8bQNz0RQ+9Uc+4J7V97gLYjZVKRjeydPgGt6dvQzFrav7MYOUGFqqOGiHpA/fdbd0cQ==" } }, "workspace": { "packageJson": { "dependencies": [ - "npm:@jsr/std__assert@1", - "npm:@jsr/std__testing@1", - "npm:eslint-plugin-simple-import-sort@12", - "npm:eslint@9", - "npm:prettier@3", - "npm:typescript-eslint@8" + "npm:@jsr/std__assert@1.0.14", + "npm:@jsr/std__testing@1.0.15", + "npm:eslint-plugin-simple-import-sort@12.1.1", + "npm:eslint@9.35.0", + "npm:prettier@3.6.2", + "npm:typescript-eslint@8.44.0" ] }, "members": { "api": { "packageJson": { "dependencies": [ - "npm:@jsr/felix__bcrypt@1", - "npm:@jsr/std__cli@1", - "npm:@jsr/std__dotenv@0.225", - "npm:@jsr/std__fs@1", - "npm:@jsr/std__path@1", - "npm:@jsr/valkyr__auth@2", - "npm:@jsr/valkyr__event-store@2.0.0-beta.6", - "npm:@jsr/valkyr__inverse@1", - "npm:@jsr/valkyr__json-rpc@1", - "npm:cookie@1", - "npm:mongodb@6", - "npm:zod@4" + "npm:@cerbos/grpc@0.23.1", + "npm:@cerbos/http@0.23.1", + "npm:@jsr/felix__bcrypt@1.0.5", + "npm:@jsr/std__cli@1.0.22", + "npm:@jsr/std__dotenv@0.225.5", + "npm:@jsr/std__fs@1.0.19", + "npm:@jsr/std__path@1.1.2", + "npm:@jsr/valkyr__auth@2.1.3", + "npm:@jsr/valkyr__event-store@2", + "npm:@jsr/valkyr__inverse@1.0.1", + "npm:@jsr/valkyr__json-rpc@1.1.0", + "npm:cookie@1.0.2", + "npm:mongodb@6.20.0", + "npm:zod@4.1.9" ] } }, "apps/react": { "packageJson": { "dependencies": [ - "npm:@eslint/js@9", - "npm:@jsr/valkyr__db@2.0.0-beta.3", - "npm:@jsr/valkyr__event-emitter@1", - "npm:@tailwindcss/vite@4", - "npm:@tanstack/react-query@5", - "npm:@tanstack/react-router-devtools@1", - "npm:@tanstack/react-router@1", - "npm:@types/react-dom@19", - "npm:@types/react@19", - "npm:@vitejs/plugin-react@4", - "npm:eslint-plugin-react-hooks@5", - "npm:eslint-plugin-react-refresh@0.4", - "npm:eslint@9", - "npm:fast-equals@5", - "npm:globals@16", - "npm:react-dom@19", - "npm:react@19", - "npm:tailwindcss@4", - "npm:typescript-eslint@8", - "npm:typescript@5", - "npm:vite@7", - "npm:zod@4" + "npm:@eslint/js@9.35.0", + "npm:@jsr/valkyr__db@2.0.0", + "npm:@jsr/valkyr__event-emitter@1.0.1", + "npm:@tailwindcss/vite@4.1.13", + "npm:@tanstack/react-query@5.89.0", + "npm:@tanstack/react-router-devtools@1.131.47", + "npm:@tanstack/react-router@1.131.47", + "npm:@types/react-dom@19.1.9", + "npm:@types/react@19.1.13", + "npm:@vitejs/plugin-react@4.7.0", + "npm:eslint-plugin-react-hooks@5.2.0", + "npm:eslint-plugin-react-refresh@0.4.20", + "npm:eslint@9.35.0", + "npm:fast-equals@5.2.2", + "npm:globals@16.4.0", + "npm:react-dom@19.1.1", + "npm:react@19.1.1", + "npm:tailwindcss@4.1.13", + "npm:typescript-eslint@8.44.0", + "npm:typescript@5.9.2", + "npm:vite@7.1.6", + "npm:zod@4.1.9" ] } }, diff --git a/docker-compose.yml b/docker-compose.yml index 58c43f8..761488a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,18 @@ services: + cerbos: + container_name: cerbos + image: ghcr.io/cerbos/cerbos:latest + command: ["server", "--config=/config.yaml"] # <--- ensure config is used + ports: + - "3592:3592" + - "3593:3593" + - "3594:3594" + volumes: + - ./cerbos/config.yaml:/config.yaml # <--- mount config + - ./cerbos/policies:/data/policies # <--- mount policies + networks: + - localdev + mongo: image: mongo:8 restart: unless-stopped diff --git a/package.json b/package.json index 1a58946..840f3a7 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,10 @@ { "devDependencies": { - "@std/assert": "npm:@jsr/std__assert@1", - "@std/testing": "npm:@jsr/std__testing@1", - "eslint": "9", - "eslint-plugin-simple-import-sort": "12", - "prettier": "3", - "typescript-eslint": "8" + "@std/assert": "npm:@jsr/std__assert@1.0.14", + "@std/testing": "npm:@jsr/std__testing@1.0.15", + "eslint": "9.35.0", + "eslint-plugin-simple-import-sort": "12.1.1", + "prettier": "3.6.2", + "typescript-eslint": "8.44.0" } } diff --git a/spec/relay/libraries/procedure.ts b/spec/relay/libraries/procedure.ts index 1334758..c5097a9 100644 --- a/spec/relay/libraries/procedure.ts +++ b/spec/relay/libraries/procedure.ts @@ -1,7 +1,7 @@ import z, { ZodType } from "zod"; import { ServerError, ServerErrorClass } from "./errors.ts"; -import { Access, ServerContext } from "./types.ts"; +import { RouteAccess, ServerContext } from "./route.ts"; export class Procedure { readonly type = "procedure" as const; @@ -64,7 +64,7 @@ export class Procedure { * }); * ``` */ - access(access: TAccess): Procedure & { access: TAccess }> { + access(access: TAccess): Procedure & { access: TAccess }> { return new Procedure({ ...this.state, access: access as TAccess }); } @@ -220,7 +220,7 @@ export type Procedures = { type State = { method: string; - access?: Access; + access?: RouteAccess; params?: ZodType; errors?: ServerErrorClass[]; response?: ZodType; diff --git a/spec/relay/libraries/route.ts b/spec/relay/libraries/route.ts index 2942648..1904ca5 100644 --- a/spec/relay/libraries/route.ts +++ b/spec/relay/libraries/route.ts @@ -3,7 +3,6 @@ import z, { ZodObject, ZodRawShape, ZodType } from "zod"; import { ServerError, ServerErrorClass } from "./errors.ts"; import { Hooks } from "./hooks.ts"; -import { ServerContext } from "./types.ts"; export class Route { readonly type = "route" as const; @@ -81,7 +80,7 @@ export class Route { * route.post("/foo").meta({ description: "Super route" }); * ``` */ - meta(meta: TRouteMeta): Route & { meta: TRouteMeta }> { + meta(meta: TRouteMeta): Route & { meta: TRouteMeta }>> { return new Route({ ...this.state, meta }); } @@ -134,7 +133,7 @@ export class Route { * }); * ``` */ - access(access: TAccess): Route & { access: TAccess }> { + access(access: TAccess): Route & { access: TAccess }>> { return new Route({ ...this.state, access: access as TAccess }); } @@ -157,7 +156,9 @@ export class Route { * }); * ``` */ - params(params: TParams): Route & { params: ZodObject }> { + params( + params: TParams, + ): Route & { params: ZodObject }>> { return new Route({ ...this.state, params: z.object(params) as any }); } @@ -180,7 +181,9 @@ export class Route { * }); * ``` */ - query(query: TQuery): Route & { query: ZodObject }> { + query( + query: TQuery, + ): Route & { query: ZodObject }>> { return new Route({ ...this.state, query: z.object(query) as any }); } @@ -205,7 +208,7 @@ export class Route { * }); * ``` */ - body(body: TBody): Route & { body: TBody }> { + body(body: TBody): Route & { body: TBody }>> { return new Route({ ...this.state, body }); } @@ -227,7 +230,9 @@ export class Route { * }); * ``` */ - errors(errors: TErrors): Route & { errors: TErrors }> { + errors( + errors: TErrors, + ): Route & { errors: TErrors }>> { return new Route({ ...this.state, errors }); } @@ -254,7 +259,9 @@ export class Route { * }); * ``` */ - response(response: TResponse): Route & { response: TResponse }> { + response( + response: TResponse, + ): Route & { response: TResponse }>> { return new Route({ ...this.state, response }); } @@ -292,7 +299,7 @@ export class Route { * * @param hooks - Hooks to register with the route. */ - hooks(hooks: THooks): Route & { hooks: THooks }> { + hooks(hooks: THooks): Route & { hooks: THooks }>> { return new Route({ ...this.state, hooks }); } } @@ -444,9 +451,10 @@ export type RouteMeta = { export type RouteMethod = "POST" | "GET" | "PUT" | "PATCH" | "DELETE"; -export type RouteAccess = "public" | "session" | (() => boolean)[]; +export type RouteAccess = "public" | "authenticated"; -export type AccessFn = (resource: string, action: string) => () => boolean; +// eslint-disable-next-line @typescript-eslint/no-empty-object-type +export interface ServerContext {} type HandleFn = any[], TResponse = any> = ( ...args: TArgs @@ -471,3 +479,7 @@ type HasInputArgs = TState["params"] extends ZodObjec : TState["body"] extends ZodType ? true : false; + +type Prettify = { + [K in keyof T]: T[K]; +} & {}; diff --git a/spec/relay/libraries/types.ts b/spec/relay/libraries/types.ts deleted file mode 100644 index 3b879af..0000000 --- a/spec/relay/libraries/types.ts +++ /dev/null @@ -1,6 +0,0 @@ -export type Access = "public" | "session" | (() => boolean)[]; - -export type AccessFn = (resource: string, action: string) => () => boolean; - -// eslint-disable-next-line @typescript-eslint/no-empty-object-type -export interface ServerContext {} diff --git a/spec/schemas/access/role.ts b/spec/schemas/access/role.ts deleted file mode 100644 index f1313d2..0000000 --- a/spec/schemas/access/role.ts +++ /dev/null @@ -1,14 +0,0 @@ -import z from "zod"; - -import { makeSchemaParser } from "../database.ts"; - -export const RoleSchema = z.object({ - id: z.uuid(), - name: z.string(), - permissions: z.record(z.string(), z.array(z.string())), -}); - -export const parseRole = makeSchemaParser(RoleSchema); - -export type Role = z.infer; -export type RoleDocument = z.infer; diff --git a/spec/schemas/account/account.ts b/spec/schemas/account/account.ts index bb45e8a..273f0af 100644 --- a/spec/schemas/account/account.ts +++ b/spec/schemas/account/account.ts @@ -1,10 +1,10 @@ import { z } from "zod"; -import { RoleSchema } from "../access/role.ts"; import { AvatarSchema } from "../avatar.ts"; import { ContactSchema } from "../contact.ts"; import { makeSchemaParser } from "../database.ts"; import { NameSchema } from "../name.ts"; +import { RoleSchema } from "./role.ts"; import { StrategySchema } from "./strategies.ts"; export const AccountSchema = z.object({ @@ -18,10 +18,8 @@ export const AccountSchema = z.object({ roles: z.array(RoleSchema).default([]), }); -export const AccountDocumentSchema = AccountSchema.omit({ roles: true }).extend({ roles: z.array(z.string()) }); - -export const toAccountDocument = makeSchemaParser(AccountDocumentSchema); +export const toAccountDocument = makeSchemaParser(AccountSchema); export const fromAccountDocument = makeSchemaParser(AccountSchema); export type Account = z.infer; -export type AccountDocument = z.infer; +export type AccountDocument = z.infer; diff --git a/spec/schemas/account/role.ts b/spec/schemas/account/role.ts new file mode 100644 index 0000000..e9ea8f4 --- /dev/null +++ b/spec/schemas/account/role.ts @@ -0,0 +1,5 @@ +import z from "zod"; + +export const RoleSchema = z.union([z.literal("user"), z.literal("admin")]); + +export type Role = z.infer; diff --git a/spec/schemas/account/routes.ts b/spec/schemas/account/routes.ts index 6610e8c..2a4322c 100644 --- a/spec/schemas/account/routes.ts +++ b/spec/schemas/account/routes.ts @@ -1,7 +1,8 @@ -import { route } from "@spec/relay"; +import { ForbiddenError, NotFoundError, route, UnauthorizedError } from "@spec/relay"; import z from "zod"; import { NameSchema } from "../name.ts"; +import { AccountSchema } from "./account.ts"; import { AccountEmailClaimedError } from "./errors.ts"; export const create = route @@ -15,6 +16,15 @@ export const create = route .errors([AccountEmailClaimedError]) .response(z.uuid()); +export const getById = route + .get("/api/v1/accounts/:id") + .params({ + id: z.string(), + }) + .errors([UnauthorizedError, ForbiddenError, NotFoundError]) + .response(AccountSchema); + export const routes = { create, + getById, };