test(server): integration test
This commit is contained in:
@@ -0,0 +1,265 @@
|
||||
import type { Database } from '../../src/libs/db'
|
||||
|
||||
import { Buffer } from 'node:buffer'
|
||||
|
||||
import { vi } from 'vitest'
|
||||
|
||||
import { buildApp } from '../../src/app'
|
||||
import { mockDB } from '../../src/libs/mock-db'
|
||||
import { createAdminFluxGrantsService } from '../../src/services/admin-flux-grants'
|
||||
import { createBillingService } from '../../src/services/billing/billing-service'
|
||||
import { createFluxService } from '../../src/services/flux'
|
||||
import { createUserDeletionService } from '../../src/services/user-deletion'
|
||||
import { userFluxRedisKey } from '../../src/utils/redis-keys'
|
||||
|
||||
import * as schema from '../../src/schemas'
|
||||
|
||||
// NOTICE:
|
||||
// drizzle-kit's `pushSchema` (called by `mockDB`) takes ~500ms per invocation.
|
||||
// Vitest spawns a fresh worker per test file, so a module-level promise scopes
|
||||
// the cache correctly: schema push runs once per file, every
|
||||
// `startVerificationContext()` after that reuses the in-memory PGlite and
|
||||
// only truncates rows. See `docs/ai/context/verification-automation.md` for
|
||||
// the broader rationale on test boot cost.
|
||||
let sharedDbPromise: Promise<Database> | null = null
|
||||
|
||||
async function getSharedDb(): Promise<Database> {
|
||||
sharedDbPromise ??= mockDB(schema)
|
||||
return sharedDbPromise
|
||||
}
|
||||
|
||||
async function resetDataRows(db: Database): Promise<void> {
|
||||
// Delete in FK-safe order. better-auth's session / account / verification
|
||||
// tables reference user with `onDelete: cascade`, so deleting `user` last
|
||||
// implicitly clears them — we still call them out for clarity and so a
|
||||
// future test that seeds sessions directly does not silently leak rows.
|
||||
await db.delete(schema.fluxTransaction)
|
||||
await db.delete(schema.userFlux)
|
||||
await db.delete(schema.session)
|
||||
await db.delete(schema.account)
|
||||
await db.delete(schema.user)
|
||||
}
|
||||
|
||||
interface SeedUserOptions {
|
||||
id: string
|
||||
email?: string
|
||||
balance: number
|
||||
}
|
||||
|
||||
interface SessionUser {
|
||||
id: string
|
||||
email: string
|
||||
emailVerified?: boolean
|
||||
name?: string
|
||||
}
|
||||
|
||||
export type Harness = Awaited<ReturnType<typeof startVerificationContext>>
|
||||
|
||||
/**
|
||||
* Boots a Hono app with the same wiring as production for a verification
|
||||
* scenario.
|
||||
*
|
||||
* Use when:
|
||||
* - You need to assert a full user path (HTTP -> route -> service -> DB / ledger)
|
||||
* rather than a unit-level code path
|
||||
* - You want real `createFluxService` + `createBillingService` against a real
|
||||
* in-memory Postgres (PGlite), with auth / OIDC / WebSocket / OTel stubbed
|
||||
*
|
||||
* Expects:
|
||||
* - No external network. The mock router never opens sockets so
|
||||
* pre-flight-rejecting cases never reach it; tests that actually need an
|
||||
* upstream LLM response must stub `fetch` themselves
|
||||
*
|
||||
* Returns:
|
||||
* - A `Harness` value with the mounted app, drizzle handle, and helpers to
|
||||
* set a session user, seed flux balance, override config keys, and inspect
|
||||
* the in-memory Redis store
|
||||
*/
|
||||
interface HarnessOptions {
|
||||
/**
|
||||
* Comma-separated email allowlist baked into `adminGuard`. Must be set at
|
||||
* boot time — the guard parses this once at route construction, so flipping
|
||||
* `ctx.env.ADMIN_EMAILS` mid-test has no effect. Tests that need to swap
|
||||
* admins should boot a fresh context.
|
||||
*/
|
||||
adminEmails?: string
|
||||
}
|
||||
|
||||
export async function startVerificationContext(opts: HarnessOptions = {}) {
|
||||
const db = await getSharedDb()
|
||||
await resetDataRows(db)
|
||||
|
||||
let activeSession: { user: any, session: any } | null = null
|
||||
|
||||
const auth: any = {
|
||||
api: {
|
||||
getSession: vi.fn(async () => activeSession),
|
||||
getOAuthServerConfig: vi.fn(async () => ({})),
|
||||
getOpenIdConfig: vi.fn(async () => ({})),
|
||||
},
|
||||
handler: vi.fn(async () => new Response('not-found', { status: 404 })),
|
||||
}
|
||||
|
||||
const configStore: Record<string, any> = {
|
||||
FLUX_PER_REQUEST: 1,
|
||||
INITIAL_USER_FLUX: 0,
|
||||
AUTH_RATE_LIMIT_MAX: 1000,
|
||||
AUTH_RATE_LIMIT_WINDOW_SEC: 60,
|
||||
FLUX_PER_1K_CHARS_TTS: 2,
|
||||
TTS_DEBT_TTL_SECONDS: 86400,
|
||||
}
|
||||
const configKV: any = {
|
||||
get: vi.fn(async (key: string) => configStore[key]),
|
||||
getOrThrow: vi.fn(async (key: string) => {
|
||||
if (configStore[key] === undefined)
|
||||
throw new Error(`Config key "${key}" is not set`)
|
||||
return configStore[key]
|
||||
}),
|
||||
getOptional: vi.fn(async (key: string) => (configStore[key] ?? null)),
|
||||
set: vi.fn(async (key: string, value: any) => {
|
||||
configStore[key] = value
|
||||
}),
|
||||
}
|
||||
|
||||
const redisStore = new Map<string, string>()
|
||||
const redisSubscriber = {
|
||||
on: vi.fn(),
|
||||
subscribe: vi.fn(async () => 1),
|
||||
unsubscribe: vi.fn(async () => 0),
|
||||
quit: vi.fn(async () => 'OK'),
|
||||
}
|
||||
const redis: any = {
|
||||
get: vi.fn(async (key: string) => redisStore.get(key) ?? null),
|
||||
getBuffer: vi.fn(async (key: string) => {
|
||||
const v = redisStore.get(key)
|
||||
return v ? Buffer.from(v, 'utf8') : null
|
||||
}),
|
||||
set: vi.fn(async (key: string, value: any) => {
|
||||
redisStore.set(key, String(value))
|
||||
return 'OK'
|
||||
}),
|
||||
del: vi.fn(async (key: string) => (redisStore.delete(key) ? 1 : 0)),
|
||||
incrby: vi.fn(async (key: string, by: number) => {
|
||||
const next = (Number.parseInt(redisStore.get(key) ?? '0', 10) || 0) + by
|
||||
redisStore.set(key, String(next))
|
||||
return next
|
||||
}),
|
||||
expire: vi.fn(async () => 1),
|
||||
duplicate: vi.fn(() => redisSubscriber),
|
||||
publish: vi.fn(async () => 0),
|
||||
}
|
||||
|
||||
const fluxService = createFluxService(db, redis, configKV)
|
||||
const billingService = createBillingService(db, redis, configKV)
|
||||
const adminFluxGrantsService = createAdminFluxGrantsService({ db, billingService })
|
||||
|
||||
// NOTICE:
|
||||
// Production wires 5 soft-delete handlers (stripe / flux / providers /
|
||||
// characters / chats). The harness only wires `flux` so the verification
|
||||
// for "balance soft-deleted + ledger preserved" can run without dragging
|
||||
// in stripe SDK, character / chat / provider services. Tests covering the
|
||||
// other 4 handlers should opt in via a future option flag rather than
|
||||
// widening the default wiring.
|
||||
const userDeletionService = createUserDeletionService()
|
||||
userDeletionService.register({
|
||||
name: 'flux',
|
||||
priority: 20,
|
||||
softDelete: ({ userId }) => fluxService.deleteAllForUser(userId),
|
||||
})
|
||||
|
||||
// NOTICE:
|
||||
// The Proxy returns a fresh vi.fn() for every property access. Stand-in for
|
||||
// services this verification doesn't touch (chat, characters, providers,
|
||||
// stripe, admin-flux-grants, user-deletion, ttsMeter). If a test exercises
|
||||
// one of these and starts getting `undefined is not a function` errors,
|
||||
// wire in a real instance instead of widening this stub.
|
||||
const stub: any = new Proxy({}, { get: () => vi.fn(async () => undefined) })
|
||||
|
||||
const env: any = {
|
||||
API_SERVER_URL: 'http://localhost:3000',
|
||||
ADMIN_EMAILS: opts.adminEmails ?? '',
|
||||
OTEL_SERVICE_NAME: 'airi-server-test',
|
||||
ADDITIONAL_TRUSTED_ORIGINS: '',
|
||||
HOST: '127.0.0.1',
|
||||
PORT: 0,
|
||||
}
|
||||
|
||||
const { app } = await buildApp({
|
||||
auth,
|
||||
db,
|
||||
characterService: stub,
|
||||
chatService: stub,
|
||||
providerService: stub,
|
||||
fluxService,
|
||||
fluxTransactionService: stub,
|
||||
stripeService: stub,
|
||||
billingService,
|
||||
adminFluxGrantsService,
|
||||
ttsMeter: stub,
|
||||
requestLogService: { logRequest: vi.fn(async () => undefined) } as any,
|
||||
configKV,
|
||||
redis,
|
||||
env,
|
||||
otel: null,
|
||||
userDeletionService,
|
||||
llmRouter: {
|
||||
route: vi.fn(async () => new Response('{}', { status: 200 })),
|
||||
invalidateConfig: vi.fn(),
|
||||
} as any,
|
||||
posthog: null,
|
||||
})
|
||||
|
||||
return {
|
||||
app,
|
||||
db,
|
||||
schema,
|
||||
redisStore,
|
||||
configStore,
|
||||
userDeletionService,
|
||||
fluxService,
|
||||
setSessionUser(user: SessionUser | null) {
|
||||
activeSession = user
|
||||
? {
|
||||
user: {
|
||||
id: user.id,
|
||||
email: user.email,
|
||||
name: user.name ?? user.id,
|
||||
emailVerified: user.emailVerified ?? true,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
},
|
||||
session: {
|
||||
id: `sess-${user.id}`,
|
||||
userId: user.id,
|
||||
token: `tok-${user.id}`,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
expiresAt: new Date(Date.now() + 3600_000),
|
||||
ipAddress: null,
|
||||
userAgent: null,
|
||||
},
|
||||
}
|
||||
: null
|
||||
},
|
||||
async seedUser(opts: SeedUserOptions) {
|
||||
await db.insert(schema.user).values({
|
||||
id: opts.id,
|
||||
name: opts.id,
|
||||
email: opts.email ?? `${opts.id}@example.com`,
|
||||
emailVerified: true,
|
||||
}).onConflictDoNothing()
|
||||
await db.insert(schema.userFlux).values({
|
||||
userId: opts.id,
|
||||
flux: opts.balance,
|
||||
}).onConflictDoNothing()
|
||||
// NOTICE:
|
||||
// Prime the Redis cache so `fluxService.getFlux()` reads the seeded
|
||||
// balance directly instead of touching the DB-init path (which would
|
||||
// create an `initial` flux_transaction row and skew ledger assertions).
|
||||
redisStore.set(userFluxRedisKey(opts.id), String(opts.balance))
|
||||
},
|
||||
setConfig(kv: Record<string, any>) {
|
||||
Object.assign(configStore, kv)
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
// Verification: docs/ai/context/verification-automation.md
|
||||
// Source doc: apps/server/docs/ai-context/verifications/account-deletion.md
|
||||
//
|
||||
// Covers one slice of the verification doc — the part that pins down
|
||||
// "Flux balance soft-deleted, cache invalidated, ledger preserved".
|
||||
//
|
||||
// What this test does NOT cover (intentional, out of harness scope):
|
||||
// - The Better Auth `/api/auth/delete-user/callback` HTTP entry point. The
|
||||
// prod trigger lives inside better-auth's plugin internals; testing it
|
||||
// end-to-end would mean mounting the real `createAuth(...)` against
|
||||
// better-auth's verification-token flow, which the harness does not do.
|
||||
// We call `userDeletionService.softDeleteAll(...)` directly — the same
|
||||
// function better-auth's `beforeDelete` hook calls — so the orchestration
|
||||
// contract is exercised even though the HTTP boundary is skipped.
|
||||
// - The stripe / providers / characters / chats handlers. The harness wires
|
||||
// only the `flux` handler (see `_harness.ts`). Verifying the other four
|
||||
// needs widening the default wiring or a per-test opt-in.
|
||||
|
||||
import type { Harness } from './_harness'
|
||||
|
||||
import { eq } from 'drizzle-orm'
|
||||
import { afterAll, beforeEach, describe, expect, it } from 'vitest'
|
||||
|
||||
import { userFluxRedisKey } from '../../src/utils/redis-keys'
|
||||
import { startVerificationContext } from './_harness'
|
||||
|
||||
describe('verification: account-deletion (flux slice)', () => {
|
||||
let ctx: Harness
|
||||
|
||||
beforeEach(async () => {
|
||||
ctx = await startVerificationContext()
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
// PGlite is module-cached and lives for the worker's lifetime.
|
||||
})
|
||||
|
||||
it('soft-deletes user_flux, invalidates redis cache, leaves flux_transaction ledger intact', async () => {
|
||||
const userId = 'user-doomed'
|
||||
|
||||
// Seed: balance 500 + one historical debit ledger row. The ledger row is
|
||||
// the load-bearing assertion — flux_transaction has no `deleted_at`
|
||||
// column on purpose, and the bare userId (no FK) is the mechanism that
|
||||
// lets the ledger outlive the user row. See `schemas/flux-transaction.ts`
|
||||
// NOTICE comment.
|
||||
await ctx.seedUser({ id: userId, balance: 500 })
|
||||
await ctx.db.insert(ctx.schema.fluxTransaction).values({
|
||||
userId,
|
||||
type: 'debit',
|
||||
amount: 50,
|
||||
balanceBefore: 550,
|
||||
balanceAfter: 500,
|
||||
description: 'prior llm call',
|
||||
})
|
||||
|
||||
// Sanity precondition: balance is 500 and ledger has 1 row.
|
||||
const balanceBefore = await ctx.fluxService.getFlux(userId)
|
||||
expect(balanceBefore.flux).toBe(500)
|
||||
expect(ctx.redisStore.get(userFluxRedisKey(userId))).toBe('500')
|
||||
const ledgerBefore = await ctx.db.query.fluxTransaction.findMany({
|
||||
where: eq(ctx.schema.fluxTransaction.userId, userId),
|
||||
})
|
||||
expect(ledgerBefore).toHaveLength(1)
|
||||
|
||||
// Act: same call better-auth makes inside the delete-user callback hook.
|
||||
await ctx.userDeletionService.softDeleteAll({ userId, reason: 'user-requested' })
|
||||
|
||||
// Assert 1: user_flux row is stamped with deletedAt (soft-delete).
|
||||
const rawRow = await ctx.db
|
||||
.select()
|
||||
.from(ctx.schema.userFlux)
|
||||
.where(eq(ctx.schema.userFlux.userId, userId))
|
||||
expect(rawRow).toHaveLength(1)
|
||||
expect(rawRow[0].deletedAt).not.toBeNull()
|
||||
expect(rawRow[0].flux).toBe(500) // balance value is NOT zeroed; soft-delete only stamps deletedAt
|
||||
|
||||
// Assert 2: redis cache for the user's balance is dropped.
|
||||
expect(ctx.redisStore.get(userFluxRedisKey(userId))).toBeUndefined()
|
||||
|
||||
// Assert 3: ledger rows persist. The audit trail outlives the user row.
|
||||
const ledgerAfter = await ctx.db.query.fluxTransaction.findMany({
|
||||
where: eq(ctx.schema.fluxTransaction.userId, userId),
|
||||
})
|
||||
expect(ledgerAfter).toHaveLength(1)
|
||||
expect(ledgerAfter[0].description).toBe('prior llm call')
|
||||
|
||||
// Assert 4: `fluxService.getFlux` rejects after soft-delete. The read
|
||||
// path filters on `deletedAt IS NULL`, the init-path's
|
||||
// `onConflictDoNothing` no-ops against the soft-deleted row, and the
|
||||
// re-read still finds nothing — so the service throws. In production
|
||||
// this scenario should not arise because better-auth hard-deletes the
|
||||
// user row after `softDeleteAll`. The throw is the defense-in-depth
|
||||
// failure mode described in the `fluxService` NOTICE for any request
|
||||
// that bypasses `sessionMiddleware` with a soft-deleted user.
|
||||
await expect(ctx.fluxService.getFlux(userId)).rejects.toThrow(/Failed to initialize flux/)
|
||||
})
|
||||
|
||||
it('softDeleteAll is idempotent — calling it twice does not throw and leaves state unchanged', async () => {
|
||||
// The handler uses `WHERE deletedAt IS NULL` so the second call finds 0
|
||||
// rows and is a no-op. `redis.del` is also a no-op when the key is
|
||||
// absent. Pinning this prevents a future refactor that tightens the
|
||||
// where-clause and accidentally requires the row to be live.
|
||||
const userId = 'user-doomed-twice'
|
||||
await ctx.seedUser({ id: userId, balance: 100 })
|
||||
|
||||
await ctx.userDeletionService.softDeleteAll({ userId, reason: 'user-requested' })
|
||||
await ctx.userDeletionService.softDeleteAll({ userId, reason: 'user-requested' })
|
||||
|
||||
const rawRow = await ctx.db
|
||||
.select()
|
||||
.from(ctx.schema.userFlux)
|
||||
.where(eq(ctx.schema.userFlux.userId, userId))
|
||||
expect(rawRow).toHaveLength(1)
|
||||
expect(rawRow[0].deletedAt).not.toBeNull()
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,169 @@
|
||||
// Verification: docs/ai/context/verification-automation.md
|
||||
// Source doc: apps/server/docs/ai-context/verifications/admin-flux-grants.md
|
||||
//
|
||||
// Covers the three user paths from the verification doc:
|
||||
// Path 1: admin POST /api/admin/flux-grants → 200 + granted array, ledger row written
|
||||
// Path 2: ?dryRun=true → preview returned, ledger unchanged
|
||||
// Path 3: adminGuard rejects (401 no session / 403 not in allowlist / 403 unverified)
|
||||
|
||||
import type { Harness } from './_harness'
|
||||
|
||||
import { eq } from 'drizzle-orm'
|
||||
import { afterAll, beforeEach, describe, expect, it } from 'vitest'
|
||||
|
||||
import { startVerificationContext } from './_harness'
|
||||
|
||||
const ADMIN_EMAIL = 'admin@example.com'
|
||||
|
||||
describe('verification: admin-flux-grants', () => {
|
||||
let ctx: Harness
|
||||
|
||||
beforeEach(async () => {
|
||||
ctx = await startVerificationContext({ adminEmails: ADMIN_EMAIL })
|
||||
ctx.setConfig({ INITIAL_USER_FLUX: 0 })
|
||||
// Admin user (caller). emailVerified is required by adminGuard.
|
||||
await ctx.seedUser({ id: 'admin-1', email: ADMIN_EMAIL, balance: 0 })
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
// PGlite is per-context and per-test — letting it drop out of scope is enough.
|
||||
})
|
||||
|
||||
describe('path 1: admin synchronously grants flux', () => {
|
||||
it('credits 100 flux to each existing recipient and returns the per-email outcome buckets', async () => {
|
||||
await ctx.seedUser({ id: 'recipient-1', email: 'rec1@example.com', balance: 0 })
|
||||
await ctx.seedUser({ id: 'recipient-2', email: 'rec2@example.com', balance: 25 })
|
||||
ctx.setSessionUser({ id: 'admin-1', email: ADMIN_EMAIL })
|
||||
|
||||
const res = await ctx.app.request('/api/admin/flux-grants', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
description: 'integration-test grant',
|
||||
amount: 100,
|
||||
emails: ['rec1@example.com', 'rec2@example.com'],
|
||||
}),
|
||||
})
|
||||
|
||||
expect(res.status).toBe(200)
|
||||
const body = await res.json() as {
|
||||
summary: { willGrant: number, totalFluxToIssue: number }
|
||||
result: {
|
||||
granted: { email: string, userId: string, fluxTransactionId: string, balanceAfter: number }[]
|
||||
skipped: unknown[]
|
||||
failed: unknown[]
|
||||
}
|
||||
}
|
||||
|
||||
expect(body.summary.willGrant).toBe(2)
|
||||
expect(body.summary.totalFluxToIssue).toBe(200)
|
||||
expect(body.result.failed).toEqual([])
|
||||
expect(body.result.skipped).toEqual([])
|
||||
expect(body.result.granted).toHaveLength(2)
|
||||
|
||||
const granted1 = body.result.granted.find(g => g.email === 'rec1@example.com')
|
||||
const granted2 = body.result.granted.find(g => g.email === 'rec2@example.com')
|
||||
expect(granted1?.balanceAfter).toBe(100)
|
||||
expect(granted2?.balanceAfter).toBe(125)
|
||||
expect(granted1?.fluxTransactionId).toBeTruthy()
|
||||
|
||||
// Ledger writes per recipient with type='promo' and the operator id in metadata.
|
||||
const rec1Ledger = await ctx.db.query.fluxTransaction.findMany({
|
||||
where: eq(ctx.schema.fluxTransaction.userId, 'recipient-1'),
|
||||
})
|
||||
expect(rec1Ledger).toHaveLength(1)
|
||||
expect(rec1Ledger[0].type).toBe('promo')
|
||||
expect(rec1Ledger[0].amount).toBe(100)
|
||||
expect(rec1Ledger[0].balanceBefore).toBe(0)
|
||||
expect(rec1Ledger[0].balanceAfter).toBe(100)
|
||||
expect(rec1Ledger[0].description).toBe('integration-test grant')
|
||||
const meta = rec1Ledger[0].metadata as { issuedByUserId?: string, description?: string }
|
||||
expect(meta?.issuedByUserId).toBe('admin-1')
|
||||
})
|
||||
})
|
||||
|
||||
describe('path 2: dry-run preview', () => {
|
||||
it('reports willGrant / notFound / duplicateInInput without writing a ledger row', async () => {
|
||||
await ctx.seedUser({ id: 'recipient-1', email: 'rec1@example.com', balance: 0 })
|
||||
ctx.setSessionUser({ id: 'admin-1', email: ADMIN_EMAIL })
|
||||
|
||||
const res = await ctx.app.request('/api/admin/flux-grants?dryRun=true', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
description: 'smoke',
|
||||
amount: 100,
|
||||
emails: [
|
||||
'rec1@example.com',
|
||||
'REC1@example.com', // case-variant duplicate
|
||||
'ghost@nope.example', // not_found
|
||||
'rec1@example.com', // exact duplicate
|
||||
],
|
||||
}),
|
||||
})
|
||||
|
||||
expect(res.status).toBe(200)
|
||||
const body = await res.json() as {
|
||||
preview: {
|
||||
totalEmails: number
|
||||
willGrant: number
|
||||
willSkip: { notFound: number, userDeleted: number, duplicateInInput: number }
|
||||
totalFluxToIssue: number
|
||||
}
|
||||
}
|
||||
expect(body.preview.totalEmails).toBe(4)
|
||||
expect(body.preview.willGrant).toBe(1)
|
||||
expect(body.preview.willSkip.notFound).toBe(1)
|
||||
expect(body.preview.willSkip.duplicateInInput).toBe(2)
|
||||
expect(body.preview.totalFluxToIssue).toBe(100)
|
||||
|
||||
// Ledger must be untouched.
|
||||
const ledger = await ctx.db.query.fluxTransaction.findMany({
|
||||
where: eq(ctx.schema.fluxTransaction.userId, 'recipient-1'),
|
||||
})
|
||||
expect(ledger).toEqual([])
|
||||
})
|
||||
})
|
||||
|
||||
describe('path 3: adminGuard rejects unauthorized callers', () => {
|
||||
it('returns 401 when no session is attached', async () => {
|
||||
ctx.setSessionUser(null)
|
||||
|
||||
const res = await ctx.app.request('/api/admin/flux-grants', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ description: 'x', amount: 1, emails: ['a@b.com'] }),
|
||||
})
|
||||
|
||||
expect(res.status).toBe(401)
|
||||
})
|
||||
|
||||
it('returns 403 when the session user is not in ADMIN_EMAILS', async () => {
|
||||
await ctx.seedUser({ id: 'normie', email: 'normie@example.com', balance: 0 })
|
||||
ctx.setSessionUser({ id: 'normie', email: 'normie@example.com', emailVerified: true })
|
||||
|
||||
const res = await ctx.app.request('/api/admin/flux-grants', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ description: 'x', amount: 1, emails: ['a@b.com'] }),
|
||||
})
|
||||
|
||||
expect(res.status).toBe(403)
|
||||
})
|
||||
|
||||
it('returns 403 when the admin email is in the allowlist but not yet verified', async () => {
|
||||
// Same email as ADMIN_EMAIL but emailVerified=false. Guards against a
|
||||
// fresh signup with an admin's address slipping past before they prove
|
||||
// ownership.
|
||||
ctx.setSessionUser({ id: 'admin-1', email: ADMIN_EMAIL, emailVerified: false })
|
||||
|
||||
const res = await ctx.app.request('/api/admin/flux-grants', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ description: 'x', amount: 1, emails: ['a@b.com'] }),
|
||||
})
|
||||
|
||||
expect(res.status).toBe(403)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,117 @@
|
||||
// Verification: docs/ai/context/verification-automation.md
|
||||
// Source doc: apps/server/docs/ai-context/verifications/flux-unbilled-exploit-fix.md
|
||||
//
|
||||
// Covers the "user path" section of the verification doc:
|
||||
// Scenario: user with 0 < balance < fallbackRate fires N concurrent LLM
|
||||
// completion requests.
|
||||
// Expected (post-patch): all N are rejected at pre-flight with 402; the
|
||||
// upstream router is never invoked; flux_transaction ledger gains
|
||||
// no 'debit' row; user_flux.flux stays at the seeded value.
|
||||
|
||||
import type { Harness } from './_harness'
|
||||
|
||||
import { and, eq } from 'drizzle-orm'
|
||||
import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'vitest'
|
||||
|
||||
import { startVerificationContext } from './_harness'
|
||||
|
||||
describe('verification: flux-unbilled-exploit-fix', () => {
|
||||
let ctx: Harness
|
||||
|
||||
beforeAll(async () => {
|
||||
ctx = await startVerificationContext()
|
||||
})
|
||||
|
||||
beforeEach(async () => {
|
||||
// Clean ledger between cases so balanceBefore / balanceAfter assertions
|
||||
// don't carry state across tests.
|
||||
await ctx.db.delete(ctx.schema.fluxTransaction)
|
||||
await ctx.db.delete(ctx.schema.userFlux)
|
||||
ctx.redisStore.clear()
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
// PGlite is in-memory — letting it fall out of scope is enough.
|
||||
})
|
||||
|
||||
it('rejects N concurrent partial-balance requests at pre-flight, never writes a debit ledger row', async () => {
|
||||
// ROOT CAUSE:
|
||||
//
|
||||
// Before commit 7267b0d6b the pre-flight gate read `if (flux.flux <= 0)`,
|
||||
// so users with `0 < balance < FLUX_PER_REQUEST` could spawn N concurrent
|
||||
// requests, each pass pre-flight, complete the upstream LLM call, and
|
||||
// race on a post-billing debit that almost always failed (insufficient
|
||||
// funds for the requested amount, full-amount rollback). Result: N free
|
||||
// LLM responses.
|
||||
//
|
||||
// After 7267b0d6b: pre-flight rejects when `flux.flux < fallbackRate`
|
||||
// before the upstream call. This test pins the after-patch behavior so
|
||||
// a regression that loosens the gate back to `<= 0` will fail here.
|
||||
|
||||
const userId = 'user-partial-balance'
|
||||
const N = 5
|
||||
|
||||
ctx.setConfig({ FLUX_PER_REQUEST: 100, FLUX_PER_1K_TOKENS: 50 })
|
||||
await ctx.seedUser({ id: userId, balance: 5 })
|
||||
ctx.setSessionUser({ id: userId, email: `${userId}@example.com` })
|
||||
|
||||
const responses = await Promise.all(
|
||||
Array.from({ length: N }, () => ctx.app.request('/api/v1/openai/chat/completions', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ model: 'auto', messages: [{ role: 'user', content: 'hi' }] }),
|
||||
})),
|
||||
)
|
||||
|
||||
// All N must be rejected before the gateway is touched.
|
||||
expect(responses).toHaveLength(N)
|
||||
for (const res of responses) {
|
||||
expect(res.status).toBe(402)
|
||||
}
|
||||
const bodies = await Promise.all(responses.map(r => r.json() as Promise<{ error: string, message: string }>))
|
||||
for (const body of bodies) {
|
||||
expect(body.error).toBe('PAYMENT_REQUIRED')
|
||||
expect(body.message).toMatch(/Insufficient flux/i)
|
||||
}
|
||||
|
||||
// Ledger must be untouched. The pre-flight reject path never reaches
|
||||
// `consumeFluxForLLM`, so no `debit` rows should exist.
|
||||
const ledger = await ctx.db.query.fluxTransaction.findMany({
|
||||
where: eq(ctx.schema.fluxTransaction.userId, userId),
|
||||
})
|
||||
expect(ledger).toEqual([])
|
||||
|
||||
// Balance must be exactly the seeded value. No drain, no rollback.
|
||||
const fluxRow = await ctx.db.query.userFlux.findFirst({
|
||||
where: and(
|
||||
eq(ctx.schema.userFlux.userId, userId),
|
||||
// Active rows only — deletedAt IS NULL is fluxService's read guard
|
||||
),
|
||||
})
|
||||
expect(fluxRow?.flux).toBe(5)
|
||||
})
|
||||
|
||||
it('allows a request when balance >= fallbackRate (pre-flight pass-through smoke check)', async () => {
|
||||
// Companion case: with sufficient balance the pre-flight gate must NOT
|
||||
// block. We don't run the request to completion (no upstream gateway
|
||||
// available in this harness), only assert that the failure mode here is
|
||||
// upstream-fetch error (not 402). This protects against a regression
|
||||
// that flips the comparison and rejects everyone.
|
||||
const userId = 'user-funded'
|
||||
|
||||
ctx.setConfig({ FLUX_PER_REQUEST: 100, FLUX_PER_1K_TOKENS: 50 })
|
||||
await ctx.seedUser({ id: userId, balance: 1000 })
|
||||
ctx.setSessionUser({ id: userId, email: `${userId}@example.com` })
|
||||
|
||||
const res = await ctx.app.request('/api/v1/openai/chat/completions', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ model: 'auto', messages: [{ role: 'user', content: 'hi' }] }),
|
||||
})
|
||||
|
||||
// Pre-flight passed -> route delegated to the mock router. The harness
|
||||
// wires `llmRouter.route` to a vi.fn that returns 200, so we only assert
|
||||
// the pre-flight gate did NOT short-circuit with 402.
|
||||
expect(res.status).not.toBe(402)
|
||||
})
|
||||
})
|
||||
Generated
+264
-119
@@ -619,10 +619,10 @@ importers:
|
||||
dependencies:
|
||||
'@better-auth/drizzle-adapter':
|
||||
specifier: ^1.6.5
|
||||
version: 1.6.5(@better-auth/core@1.4.21(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.1.1))(@better-auth/utils@0.3.0)(drizzle-orm@0.45.2(@electric-sql/pglite@0.4.4)(@opentelemetry/api@1.9.1)(@prisma/client@5.22.0)(@types/pg@8.20.0)(better-sqlite3@12.5.0)(kysely@0.28.14)(pg@8.20.0)(postgres@3.4.9))
|
||||
version: 1.6.5(@better-auth/core@1.6.5(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.1.1))(@better-auth/utils@0.4.0)(drizzle-orm@0.45.2(@electric-sql/pglite@0.4.4)(@opentelemetry/api@1.9.1)(@prisma/client@5.22.0)(@types/pg@8.20.0)(better-sqlite3@12.5.0)(kysely@0.28.14)(pg@8.20.0)(postgres@3.4.9))
|
||||
'@better-auth/oauth-provider':
|
||||
specifier: 'catalog:'
|
||||
version: 1.5.6(@better-auth/core@1.4.21(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.1.1))(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-auth@1.6.5(@opentelemetry/api@1.9.1)(@prisma/client@5.22.0)(better-sqlite3@12.5.0)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@electric-sql/pglite@0.4.4)(@opentelemetry/api@1.9.1)(@prisma/client@5.22.0)(@types/pg@8.20.0)(better-sqlite3@12.5.0)(kysely@0.28.14)(pg@8.20.0)(postgres@3.4.9))(pg@8.20.0)(react@19.2.3)(vitest@4.1.4)(vue@3.5.32(typescript@5.9.3)))(better-call@1.1.8(zod@4.3.6))
|
||||
version: 1.5.6(@better-auth/core@1.6.5(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.1.1))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-auth@1.6.5(@opentelemetry/api@1.9.1)(@prisma/client@5.22.0)(better-sqlite3@12.5.0)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@electric-sql/pglite@0.4.4)(@opentelemetry/api@1.9.1)(@prisma/client@5.22.0)(@types/pg@8.20.0)(better-sqlite3@12.5.0)(kysely@0.28.14)(pg@8.20.0)(postgres@3.4.9))(pg@8.20.0)(react@19.2.3)(vitest@4.1.4)(vue@3.5.32(typescript@5.9.3)))(better-call@1.3.5(zod@4.3.6))
|
||||
'@dotenvx/dotenvx':
|
||||
specifier: ^1.61.1
|
||||
version: 1.61.1
|
||||
@@ -755,7 +755,7 @@ importers:
|
||||
devDependencies:
|
||||
'@better-auth/cli':
|
||||
specifier: ^1.4.21
|
||||
version: 1.4.21(@better-fetch/fetch@1.1.21)(@electric-sql/pglite@0.4.4)(@opentelemetry/api@1.9.1)(better-call@1.1.8(zod@4.3.6))(drizzle-kit@0.31.10)(jose@6.2.2)(kysely@0.28.14)(magicast@0.5.2)(nanostores@1.1.1)(postgres@3.4.9)(react@19.2.3)(vitest@4.1.4)(vue@3.5.32(typescript@5.9.3))
|
||||
version: 1.4.21(@better-fetch/fetch@1.1.21)(@electric-sql/pglite@0.4.4)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.3.6))(drizzle-kit@0.31.10)(jose@6.2.2)(kysely@0.28.14)(magicast@0.5.2)(nanostores@1.1.1)(postgres@3.4.9)(react@19.2.3)(vitest@4.1.4)(vue@3.5.32(typescript@5.9.3))
|
||||
'@types/pg':
|
||||
specifier: ^8.20.0
|
||||
version: 8.20.0
|
||||
@@ -1465,7 +1465,7 @@ importers:
|
||||
version: 3.0.2(electron@41.2.1)
|
||||
'@electron-toolkit/tsconfig':
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0(@types/node@25.6.0)
|
||||
version: 2.0.0(@types/node@24.12.2)
|
||||
'@electron-toolkit/utils':
|
||||
specifier: ^4.0.0
|
||||
version: 4.0.0(electron@41.2.1)
|
||||
@@ -1504,7 +1504,7 @@ importers:
|
||||
version: 3.1.0
|
||||
'@intlify/unplugin-vue-i18n':
|
||||
specifier: ^11.0.7
|
||||
version: 11.0.7(@vue/compiler-dom@3.5.32)(eslint@10.2.1(jiti@2.6.1))(rollup@4.60.1)(typescript@5.9.3)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(vue-i18n@11.3.2(vue@3.5.32(typescript@5.9.3)))(vue@3.5.32(typescript@5.9.3))
|
||||
version: 11.0.7(@vue/compiler-dom@3.5.32)(eslint@10.2.1(jiti@2.6.1))(rollup@4.60.1)(typescript@5.9.3)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(vue-i18n@11.3.2(vue@3.5.32(typescript@5.9.3)))(vue@3.5.32(typescript@5.9.3))
|
||||
'@modelcontextprotocol/sdk':
|
||||
specifier: 'catalog:'
|
||||
version: 1.29.0(@cfworker/json-schema@4.1.1)(zod@4.3.6)
|
||||
@@ -1540,10 +1540,10 @@ importers:
|
||||
version: link:../../packages/ui-transitions
|
||||
'@proj-airi/unplugin-fetch':
|
||||
specifier: 'catalog:'
|
||||
version: 0.2.3(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
|
||||
version: 0.2.3(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
|
||||
'@proj-airi/unplugin-live2d-sdk':
|
||||
specifier: ^0.1.7
|
||||
version: 0.1.7(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
|
||||
version: 0.1.7(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
|
||||
'@types/audioworklet':
|
||||
specifier: 'catalog:'
|
||||
version: 0.0.97
|
||||
@@ -1570,7 +1570,7 @@ importers:
|
||||
version: 2.10.3
|
||||
'@vitejs/plugin-vue':
|
||||
specifier: ^6.0.6
|
||||
version: 6.0.6(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(vue@3.5.32(typescript@5.9.3))
|
||||
version: 6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(vue@3.5.32(typescript@5.9.3))
|
||||
'@vue-macros/volar':
|
||||
specifier: ^3.1.2
|
||||
version: 3.1.2(typescript@5.9.3)(vue-tsc@3.2.6(typescript@5.9.3))(vue@3.5.32(typescript@5.9.3))
|
||||
@@ -1603,7 +1603,7 @@ importers:
|
||||
version: 6.8.3
|
||||
electron-vite:
|
||||
specifier: ^5.0.0
|
||||
version: 5.0.0(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
|
||||
version: 5.0.0(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
|
||||
get-port-please:
|
||||
specifier: 'catalog:'
|
||||
version: 3.2.0
|
||||
@@ -1624,31 +1624,31 @@ importers:
|
||||
version: 2.2.6
|
||||
unocss-preset-scrollbar:
|
||||
specifier: ^4.0.0
|
||||
version: 4.0.0(unocss@66.6.8(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))
|
||||
version: 4.0.0(unocss@66.6.8(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))
|
||||
unplugin-info:
|
||||
specifier: ^1.3.2
|
||||
version: 1.3.2(esbuild@0.27.2)(rollup@4.60.1)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
|
||||
version: 1.3.2(esbuild@0.27.2)(rollup@4.60.1)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
|
||||
unplugin-yaml:
|
||||
specifier: ^4.1.0
|
||||
version: 4.1.0(@nuxt/kit@3.20.2(magicast@0.5.2))(esbuild@0.27.2)(rolldown@1.0.0-rc.16)(rollup@4.60.1)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
|
||||
version: 4.1.0(esbuild@0.27.2)(rolldown@1.0.0-rc.16)(rollup@4.60.1)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
|
||||
vite:
|
||||
specifier: 'catalog:'
|
||||
version: 8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
|
||||
version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
|
||||
vite-bundle-visualizer:
|
||||
specifier: ^1.2.1
|
||||
version: 1.2.1(rolldown@1.0.0-rc.16)(rollup@4.60.1)
|
||||
vite-plugin-mkcert:
|
||||
specifier: 'catalog:'
|
||||
version: 2.0.0(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
|
||||
version: 2.0.0(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
|
||||
vite-plugin-vue-devtools:
|
||||
specifier: ^8.1.1
|
||||
version: 8.1.1(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(vue@3.5.32(typescript@5.9.3))
|
||||
version: 8.1.1(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(vue@3.5.32(typescript@5.9.3))
|
||||
vite-plugin-vue-layouts:
|
||||
specifier: ^0.11.0
|
||||
version: 0.11.0(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(vue-router@5.0.4(@pinia/colada@1.2.1(pinia@3.0.4(typescript@5.9.3)(vue@3.5.32(typescript@5.9.3)))(vue@3.5.32(typescript@5.9.3)))(@vue/compiler-sfc@3.5.32)(pinia@3.0.4(typescript@5.9.3)(vue@3.5.32(typescript@5.9.3)))(vue@3.5.32(typescript@5.9.3)))(vue@3.5.32(typescript@5.9.3))
|
||||
version: 0.11.0(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(vue-router@5.0.4(@pinia/colada@1.2.1(pinia@3.0.4(typescript@5.9.3)(vue@3.5.32(typescript@5.9.3)))(vue@3.5.32(typescript@5.9.3)))(@vue/compiler-sfc@3.5.32)(pinia@3.0.4(typescript@5.9.3)(vue@3.5.32(typescript@5.9.3)))(vue@3.5.32(typescript@5.9.3)))(vue@3.5.32(typescript@5.9.3))
|
||||
vue-macros:
|
||||
specifier: ^3.1.2
|
||||
version: 3.1.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@vueuse/core@14.2.1(vue@3.5.32(typescript@5.9.3)))(esbuild@0.27.2)(rolldown@1.0.0-rc.16)(rollup@4.60.1)(typescript@5.9.3)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(vue-tsc@3.2.6(typescript@5.9.3))(vue@3.5.32(typescript@5.9.3))
|
||||
version: 3.1.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@vueuse/core@14.2.1(vue@3.5.32(typescript@5.9.3)))(esbuild@0.27.2)(rolldown@1.0.0-rc.16)(rollup@4.60.1)(typescript@5.9.3)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(vue-tsc@3.2.6(typescript@5.9.3))(vue@3.5.32(typescript@5.9.3))
|
||||
vue-tsc:
|
||||
specifier: ^3.2.6
|
||||
version: 3.2.6(typescript@5.9.3)
|
||||
@@ -19334,13 +19334,13 @@ snapshots:
|
||||
|
||||
'@bcoe/v8-coverage@1.0.2': {}
|
||||
|
||||
'@better-auth/cli@1.4.21(@better-fetch/fetch@1.1.21)(@electric-sql/pglite@0.4.4)(@opentelemetry/api@1.9.1)(better-call@1.1.8(zod@4.3.6))(drizzle-kit@0.31.10)(jose@6.2.2)(kysely@0.28.14)(magicast@0.5.2)(nanostores@1.1.1)(postgres@3.4.9)(react@19.2.3)(vitest@4.1.4)(vue@3.5.32(typescript@5.9.3))':
|
||||
'@better-auth/cli@1.4.21(@better-fetch/fetch@1.1.21)(@electric-sql/pglite@0.4.4)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.3.6))(drizzle-kit@0.31.10)(jose@6.2.2)(kysely@0.28.14)(magicast@0.5.2)(nanostores@1.1.1)(postgres@3.4.9)(react@19.2.3)(vitest@4.1.4)(vue@3.5.32(typescript@5.9.3))':
|
||||
dependencies:
|
||||
'@babel/core': 7.29.0
|
||||
'@babel/preset-react': 7.28.5(@babel/core@7.29.0)
|
||||
'@babel/preset-typescript': 7.28.5(@babel/core@7.29.0)
|
||||
'@better-auth/core': 1.4.21(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.1.1)
|
||||
'@better-auth/telemetry': 1.4.21(@better-auth/core@1.4.21(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.1.1))
|
||||
'@better-auth/core': 1.4.21(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.1.1)
|
||||
'@better-auth/telemetry': 1.4.21(@better-auth/core@1.4.21(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.1.1))
|
||||
'@better-auth/utils': 0.3.0
|
||||
'@clack/prompts': 0.11.0
|
||||
'@mrleebo/prisma-ast': 0.13.1
|
||||
@@ -19417,6 +19417,17 @@ snapshots:
|
||||
nanostores: 1.1.1
|
||||
zod: 4.3.6
|
||||
|
||||
'@better-auth/core@1.4.21(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.1.1)':
|
||||
dependencies:
|
||||
'@better-auth/utils': 0.3.0
|
||||
'@better-fetch/fetch': 1.1.21
|
||||
'@standard-schema/spec': 1.1.0
|
||||
better-call: 1.3.5(zod@4.3.6)
|
||||
jose: 6.2.2
|
||||
kysely: 0.28.14
|
||||
nanostores: 1.1.1
|
||||
zod: 4.3.6
|
||||
|
||||
'@better-auth/core@1.6.5(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.1.1)':
|
||||
dependencies:
|
||||
'@better-auth/utils': 0.4.0
|
||||
@@ -19430,13 +19441,6 @@ snapshots:
|
||||
nanostores: 1.1.1
|
||||
zod: 4.3.6
|
||||
|
||||
'@better-auth/drizzle-adapter@1.6.5(@better-auth/core@1.4.21(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.1.1))(@better-auth/utils@0.3.0)(drizzle-orm@0.45.2(@electric-sql/pglite@0.4.4)(@opentelemetry/api@1.9.1)(@prisma/client@5.22.0)(@types/pg@8.20.0)(better-sqlite3@12.5.0)(kysely@0.28.14)(pg@8.20.0)(postgres@3.4.9))':
|
||||
dependencies:
|
||||
'@better-auth/core': 1.4.21(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.1.1)
|
||||
'@better-auth/utils': 0.3.0
|
||||
optionalDependencies:
|
||||
drizzle-orm: 0.45.2(@electric-sql/pglite@0.4.4)(@opentelemetry/api@1.9.1)(@prisma/client@5.22.0)(@types/pg@8.20.0)(better-sqlite3@12.5.0)(kysely@0.28.14)(pg@8.20.0)(postgres@3.4.9)
|
||||
|
||||
'@better-auth/drizzle-adapter@1.6.5(@better-auth/core@1.6.5(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.1.1))(@better-auth/utils@0.4.0)(drizzle-orm@0.45.2(@electric-sql/pglite@0.4.4)(@opentelemetry/api@1.9.1)(@prisma/client@5.22.0)(@types/pg@8.20.0)(better-sqlite3@12.5.0)(kysely@0.28.14)(pg@8.20.0)(postgres@3.4.9))':
|
||||
dependencies:
|
||||
'@better-auth/core': 1.6.5(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.1.1)
|
||||
@@ -19461,13 +19465,13 @@ snapshots:
|
||||
'@better-auth/core': 1.6.5(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.1.1)
|
||||
'@better-auth/utils': 0.4.0
|
||||
|
||||
'@better-auth/oauth-provider@1.5.6(@better-auth/core@1.4.21(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.1.1))(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-auth@1.6.5(@opentelemetry/api@1.9.1)(@prisma/client@5.22.0)(better-sqlite3@12.5.0)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@electric-sql/pglite@0.4.4)(@opentelemetry/api@1.9.1)(@prisma/client@5.22.0)(@types/pg@8.20.0)(better-sqlite3@12.5.0)(kysely@0.28.14)(pg@8.20.0)(postgres@3.4.9))(pg@8.20.0)(react@19.2.3)(vitest@4.1.4)(vue@3.5.32(typescript@5.9.3)))(better-call@1.1.8(zod@4.3.6))':
|
||||
'@better-auth/oauth-provider@1.5.6(@better-auth/core@1.6.5(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.1.1))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-auth@1.6.5(@opentelemetry/api@1.9.1)(@prisma/client@5.22.0)(better-sqlite3@12.5.0)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@electric-sql/pglite@0.4.4)(@opentelemetry/api@1.9.1)(@prisma/client@5.22.0)(@types/pg@8.20.0)(better-sqlite3@12.5.0)(kysely@0.28.14)(pg@8.20.0)(postgres@3.4.9))(pg@8.20.0)(react@19.2.3)(vitest@4.1.4)(vue@3.5.32(typescript@5.9.3)))(better-call@1.3.5(zod@4.3.6))':
|
||||
dependencies:
|
||||
'@better-auth/core': 1.4.21(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.1.1)
|
||||
'@better-auth/utils': 0.3.0
|
||||
'@better-auth/core': 1.6.5(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.5(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.1.1)
|
||||
'@better-auth/utils': 0.4.0
|
||||
'@better-fetch/fetch': 1.1.21
|
||||
better-auth: 1.6.5(@opentelemetry/api@1.9.1)(@prisma/client@5.22.0)(better-sqlite3@12.5.0)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@electric-sql/pglite@0.4.4)(@opentelemetry/api@1.9.1)(@prisma/client@5.22.0)(@types/pg@8.20.0)(better-sqlite3@12.5.0)(kysely@0.28.14)(pg@8.20.0)(postgres@3.4.9))(pg@8.20.0)(react@19.2.3)(vitest@4.1.4)(vue@3.5.32(typescript@5.9.3))
|
||||
better-call: 1.1.8(zod@4.3.6)
|
||||
better-call: 1.3.5(zod@4.3.6)
|
||||
jose: 6.2.2
|
||||
zod: 4.3.6
|
||||
|
||||
@@ -19478,9 +19482,9 @@ snapshots:
|
||||
optionalDependencies:
|
||||
'@prisma/client': 5.22.0
|
||||
|
||||
'@better-auth/telemetry@1.4.21(@better-auth/core@1.4.21(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.1.1))':
|
||||
'@better-auth/telemetry@1.4.21(@better-auth/core@1.4.21(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.1.1))':
|
||||
dependencies:
|
||||
'@better-auth/core': 1.4.21(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.1.1)
|
||||
'@better-auth/core': 1.4.21(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.1.1)
|
||||
'@better-auth/utils': 0.3.0
|
||||
'@better-fetch/fetch': 1.1.21
|
||||
|
||||
@@ -19836,9 +19840,9 @@ snapshots:
|
||||
dependencies:
|
||||
electron: 41.2.1
|
||||
|
||||
'@electron-toolkit/tsconfig@2.0.0(@types/node@25.6.0)':
|
||||
'@electron-toolkit/tsconfig@2.0.0(@types/node@24.12.2)':
|
||||
dependencies:
|
||||
'@types/node': 25.6.0
|
||||
'@types/node': 24.12.2
|
||||
|
||||
'@electron-toolkit/utils@4.0.0(electron@41.2.1)':
|
||||
dependencies:
|
||||
@@ -20732,6 +20736,31 @@ snapshots:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
'@intlify/unplugin-vue-i18n@11.0.7(@vue/compiler-dom@3.5.32)(eslint@10.2.1(jiti@2.6.1))(rollup@4.60.1)(typescript@5.9.3)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(vue-i18n@11.3.2(vue@3.5.32(typescript@5.9.3)))(vue@3.5.32(typescript@5.9.3))':
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.9.1(eslint@10.2.1(jiti@2.6.1))
|
||||
'@intlify/bundle-utils': 11.0.7(vue-i18n@11.3.2(vue@3.5.32(typescript@5.9.3)))
|
||||
'@intlify/shared': 11.3.2
|
||||
'@intlify/vue-i18n-extensions': 8.0.0(@intlify/shared@11.3.2)(@vue/compiler-dom@3.5.32)(vue-i18n@11.3.2(vue@3.5.32(typescript@5.9.3)))(vue@3.5.32(typescript@5.9.3))
|
||||
'@rollup/pluginutils': 5.3.0(rollup@4.60.1)
|
||||
'@typescript-eslint/scope-manager': 8.58.1
|
||||
'@typescript-eslint/typescript-estree': 8.58.1(typescript@5.9.3)
|
||||
debug: 4.4.3(supports-color@10.2.2)
|
||||
fast-glob: 3.3.3
|
||||
pathe: 2.0.3
|
||||
picocolors: 1.1.1
|
||||
unplugin: 2.3.11
|
||||
vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
|
||||
vue: 3.5.32(typescript@5.9.3)
|
||||
optionalDependencies:
|
||||
vue-i18n: 11.3.2(vue@3.5.32(typescript@5.9.3))
|
||||
transitivePeerDependencies:
|
||||
- '@vue/compiler-dom'
|
||||
- eslint
|
||||
- rollup
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
'@intlify/unplugin-vue-i18n@11.0.7(@vue/compiler-dom@3.5.32)(eslint@10.2.1(jiti@2.6.1))(rollup@4.60.1)(typescript@5.9.3)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(vue-i18n@11.3.2(vue@3.5.32(typescript@5.9.3)))(vue@3.5.32(typescript@5.9.3))':
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.9.1(eslint@10.2.1(jiti@2.6.1))
|
||||
@@ -22713,11 +22742,35 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- magicast
|
||||
|
||||
'@proj-airi/unplugin-fetch@0.2.3(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))':
|
||||
dependencies:
|
||||
ofetch: 1.5.1
|
||||
vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
|
||||
|
||||
'@proj-airi/unplugin-fetch@0.2.3(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))':
|
||||
dependencies:
|
||||
ofetch: 1.5.1
|
||||
vite: 8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
|
||||
|
||||
'@proj-airi/unplugin-live2d-sdk@0.1.7(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)':
|
||||
dependencies:
|
||||
ofetch: 1.5.1
|
||||
vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
|
||||
yauzl: 3.3.0
|
||||
transitivePeerDependencies:
|
||||
- '@types/node'
|
||||
- '@vitejs/devtools'
|
||||
- esbuild
|
||||
- jiti
|
||||
- less
|
||||
- sass
|
||||
- sass-embedded
|
||||
- stylus
|
||||
- sugarss
|
||||
- terser
|
||||
- tsx
|
||||
- yaml
|
||||
|
||||
'@proj-airi/unplugin-live2d-sdk@0.1.7(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)':
|
||||
dependencies:
|
||||
ofetch: 1.5.1
|
||||
@@ -23618,6 +23671,7 @@ snapshots:
|
||||
'@types/node@25.6.0':
|
||||
dependencies:
|
||||
undici-types: 7.19.2
|
||||
optional: true
|
||||
|
||||
'@types/nprogress@0.2.3': {}
|
||||
|
||||
@@ -24283,26 +24337,18 @@ snapshots:
|
||||
vite: 6.4.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
|
||||
vue: 3.5.32(typescript@5.9.3)
|
||||
|
||||
'@vitejs/plugin-vue@6.0.6(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(vue@3.5.32(typescript@5.9.3))':
|
||||
dependencies:
|
||||
'@rolldown/pluginutils': 1.0.0-rc.13
|
||||
vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
|
||||
vue: 3.5.32(typescript@5.9.3)
|
||||
|
||||
'@vitejs/plugin-vue@6.0.6(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(vue@3.5.32(typescript@5.9.3))':
|
||||
dependencies:
|
||||
'@rolldown/pluginutils': 1.0.0-rc.13
|
||||
vite: 8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
|
||||
vue: 3.5.32(typescript@5.9.3)
|
||||
|
||||
'@vitest/browser-playwright@4.1.4(bufferutil@4.1.0)(playwright@1.59.1)(utf-8-validate@5.0.10)(vite@6.4.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.4)':
|
||||
dependencies:
|
||||
'@vitest/browser': 4.1.4(bufferutil@4.1.0)(utf-8-validate@5.0.10)(vite@6.4.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.4)
|
||||
'@vitest/mocker': 4.1.4(vite@6.4.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
|
||||
playwright: 1.59.1
|
||||
tinyrainbow: 3.1.0
|
||||
vitest: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@25.6.0)(@vitest/browser-playwright@4.1.4)(@vitest/coverage-v8@4.1.4)(jsdom@29.0.2(@noble/hashes@2.0.1)(canvas@3.2.3))(vite@6.4.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- msw
|
||||
- utf-8-validate
|
||||
- vite
|
||||
optional: true
|
||||
|
||||
'@vitest/browser-playwright@4.1.4(bufferutil@4.1.0)(playwright@1.59.1)(utf-8-validate@5.0.10)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.4)':
|
||||
dependencies:
|
||||
'@vitest/browser': 4.1.4(bufferutil@4.1.0)(utf-8-validate@5.0.10)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.4)
|
||||
@@ -24330,24 +24376,6 @@ snapshots:
|
||||
- vite
|
||||
optional: true
|
||||
|
||||
'@vitest/browser@4.1.4(bufferutil@4.1.0)(utf-8-validate@5.0.10)(vite@6.4.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.4)':
|
||||
dependencies:
|
||||
'@blazediff/core': 1.9.1
|
||||
'@vitest/mocker': 4.1.4(vite@6.4.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
|
||||
'@vitest/utils': 4.1.4
|
||||
magic-string: 0.30.21
|
||||
pngjs: 7.0.0
|
||||
sirv: 3.0.2
|
||||
tinyrainbow: 3.1.0
|
||||
vitest: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@25.6.0)(@vitest/browser-playwright@4.1.4)(@vitest/coverage-v8@4.1.4)(jsdom@29.0.2(@noble/hashes@2.0.1)(canvas@3.2.3))(vite@6.4.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
|
||||
ws: 8.20.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- msw
|
||||
- utf-8-validate
|
||||
- vite
|
||||
optional: true
|
||||
|
||||
'@vitest/browser@4.1.4(bufferutil@4.1.0)(utf-8-validate@5.0.10)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.4)':
|
||||
dependencies:
|
||||
'@blazediff/core': 1.9.1
|
||||
@@ -24395,9 +24423,9 @@ snapshots:
|
||||
obug: 2.1.1
|
||||
std-env: 4.1.0
|
||||
tinyrainbow: 3.1.0
|
||||
vitest: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@25.6.0)(@vitest/browser-playwright@4.1.4)(@vitest/coverage-v8@4.1.4)(jsdom@29.0.2(@noble/hashes@2.0.1)(canvas@3.2.3))(vite@6.4.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
|
||||
vitest: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(@vitest/browser-playwright@4.1.4)(@vitest/coverage-v8@4.1.4)(jsdom@29.0.2(@noble/hashes@2.0.1)(canvas@3.2.3))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
|
||||
optionalDependencies:
|
||||
'@vitest/browser': 4.1.4(bufferutil@4.1.0)(utf-8-validate@5.0.10)(vite@6.4.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.4)
|
||||
'@vitest/browser': 4.1.4(bufferutil@4.1.0)(utf-8-validate@5.0.10)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.4)
|
||||
|
||||
'@vitest/eslint-plugin@1.6.15(@typescript-eslint/eslint-plugin@8.58.1(@typescript-eslint/parser@8.58.1(eslint@10.2.1(jiti@2.6.1))(typescript@5.9.3))(eslint@10.2.1(jiti@2.6.1))(typescript@5.9.3))(eslint@10.2.1(jiti@2.6.1))(typescript@5.9.3)(vitest@4.1.4)':
|
||||
dependencies:
|
||||
@@ -24420,14 +24448,6 @@ snapshots:
|
||||
chai: 6.2.2
|
||||
tinyrainbow: 3.1.0
|
||||
|
||||
'@vitest/mocker@4.1.4(vite@6.4.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))':
|
||||
dependencies:
|
||||
'@vitest/spy': 4.1.4
|
||||
estree-walker: 3.0.3
|
||||
magic-string: 0.30.21
|
||||
optionalDependencies:
|
||||
vite: 6.4.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
|
||||
|
||||
'@vitest/mocker@4.1.4(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))':
|
||||
dependencies:
|
||||
'@vitest/spy': 4.1.4
|
||||
@@ -24625,6 +24645,15 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- vue
|
||||
|
||||
'@vue-macros/devtools@3.1.2(typescript@5.9.3)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))':
|
||||
dependencies:
|
||||
sirv: 3.0.2
|
||||
vue: 3.5.32(typescript@5.9.3)
|
||||
optionalDependencies:
|
||||
vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
|
||||
transitivePeerDependencies:
|
||||
- typescript
|
||||
|
||||
'@vue-macros/devtools@3.1.2(typescript@5.9.3)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))':
|
||||
dependencies:
|
||||
sirv: 3.0.2
|
||||
@@ -25537,7 +25566,7 @@ snapshots:
|
||||
better-auth@1.4.21(@prisma/client@5.22.0)(better-sqlite3@12.5.0)(drizzle-kit@0.31.10)(drizzle-orm@0.41.0(@electric-sql/pglite@0.4.4)(@opentelemetry/api@1.9.1)(@prisma/client@5.22.0)(@types/pg@8.20.0)(better-sqlite3@12.5.0)(kysely@0.28.14)(pg@8.20.0)(postgres@3.4.9))(pg@8.20.0)(react@19.2.3)(vitest@4.1.4)(vue@3.5.32(typescript@5.9.3)):
|
||||
dependencies:
|
||||
'@better-auth/core': 1.4.21(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.1.1)
|
||||
'@better-auth/telemetry': 1.4.21(@better-auth/core@1.4.21(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.1.1))
|
||||
'@better-auth/telemetry': 1.4.21(@better-auth/core@1.4.21(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.1.1))
|
||||
'@better-auth/utils': 0.3.0
|
||||
'@better-fetch/fetch': 1.1.21
|
||||
'@noble/ciphers': 2.1.1
|
||||
@@ -25584,7 +25613,7 @@ snapshots:
|
||||
drizzle-orm: 0.45.2(@electric-sql/pglite@0.4.4)(@opentelemetry/api@1.9.1)(@prisma/client@5.22.0)(@types/pg@8.20.0)(better-sqlite3@12.5.0)(kysely@0.28.14)(pg@8.20.0)(postgres@3.4.9)
|
||||
pg: 8.20.0
|
||||
react: 19.2.3
|
||||
vitest: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@25.6.0)(@vitest/browser-playwright@4.1.4)(@vitest/coverage-v8@4.1.4)(jsdom@29.0.2(@noble/hashes@2.0.1)(canvas@3.2.3))(vite@6.4.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
|
||||
vitest: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@25.6.0)(@vitest/browser-playwright@4.1.4)(@vitest/coverage-v8@4.1.4)(jsdom@29.0.2(@noble/hashes@2.0.1)(canvas@3.2.3))(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
|
||||
vue: 3.5.32(typescript@5.9.3)
|
||||
transitivePeerDependencies:
|
||||
- '@cloudflare/workers-types'
|
||||
@@ -26766,7 +26795,7 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
electron-vite@5.0.0(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)):
|
||||
electron-vite@5.0.0(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)):
|
||||
dependencies:
|
||||
'@babel/core': 7.29.0
|
||||
'@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.29.0)
|
||||
@@ -26774,7 +26803,7 @@ snapshots:
|
||||
esbuild: 0.25.12
|
||||
magic-string: 0.30.21
|
||||
picocolors: 1.1.1
|
||||
vite: 8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
|
||||
vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -32684,7 +32713,8 @@ snapshots:
|
||||
|
||||
undici-types@7.16.0: {}
|
||||
|
||||
undici-types@7.19.2: {}
|
||||
undici-types@7.19.2:
|
||||
optional: true
|
||||
|
||||
undici@6.24.1: {}
|
||||
|
||||
@@ -32796,11 +32826,6 @@ snapshots:
|
||||
'@unocss/preset-mini': 66.6.8
|
||||
unocss: 66.6.8(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
|
||||
|
||||
unocss-preset-scrollbar@4.0.0(unocss@66.6.8(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))):
|
||||
dependencies:
|
||||
'@unocss/preset-mini': 66.6.8
|
||||
unocss: 66.6.8(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
|
||||
|
||||
unocss@66.6.8(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(vite@6.4.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)):
|
||||
dependencies:
|
||||
'@unocss/cli': 66.6.8
|
||||
@@ -32897,6 +32922,14 @@ snapshots:
|
||||
unplugin: 2.3.11
|
||||
vite: 8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
|
||||
|
||||
unplugin-combine@2.3.0(esbuild@0.27.2)(rolldown@1.0.0-rc.16)(rollup@4.60.1)(unplugin@2.3.11)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)):
|
||||
optionalDependencies:
|
||||
esbuild: 0.27.2
|
||||
rolldown: 1.0.0-rc.16
|
||||
rollup: 4.60.1
|
||||
unplugin: 2.3.11
|
||||
vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
|
||||
|
||||
unplugin-combine@2.3.0(esbuild@0.27.2)(rolldown@1.0.0-rc.16)(rollup@4.60.1)(unplugin@2.3.11)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)):
|
||||
optionalDependencies:
|
||||
esbuild: 0.27.2
|
||||
@@ -32931,6 +32964,19 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
unplugin-info@1.3.2(esbuild@0.27.2)(rollup@4.60.1)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)):
|
||||
dependencies:
|
||||
ci-info: 4.4.0
|
||||
git-url-parse: 16.1.0
|
||||
simple-git: 3.36.0
|
||||
unplugin: 2.3.11
|
||||
optionalDependencies:
|
||||
esbuild: 0.27.2
|
||||
rollup: 4.60.1
|
||||
vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
unplugin-info@1.3.2(esbuild@0.27.2)(rollup@4.60.1)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)):
|
||||
dependencies:
|
||||
ci-info: 4.4.0
|
||||
@@ -33040,6 +33086,17 @@ snapshots:
|
||||
rollup: 4.60.1
|
||||
vite: 6.4.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
|
||||
|
||||
unplugin-yaml@4.1.0(esbuild@0.27.2)(rolldown@1.0.0-rc.16)(rollup@4.60.1)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)):
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 5.3.0(rollup@4.60.1)
|
||||
unplugin: 3.0.0
|
||||
yaml: 2.8.3
|
||||
optionalDependencies:
|
||||
esbuild: 0.27.2
|
||||
rolldown: 1.0.0-rc.16
|
||||
rollup: 4.60.1
|
||||
vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
|
||||
|
||||
unplugin@2.3.11:
|
||||
dependencies:
|
||||
'@jridgewell/remapping': 2.3.5
|
||||
@@ -33271,12 +33328,22 @@ snapshots:
|
||||
- rollup
|
||||
- supports-color
|
||||
|
||||
vite-dev-rpc@1.1.0(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)):
|
||||
dependencies:
|
||||
birpc: 2.9.0
|
||||
vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
|
||||
vite-hot-client: 2.1.0(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
|
||||
|
||||
vite-dev-rpc@1.1.0(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)):
|
||||
dependencies:
|
||||
birpc: 2.9.0
|
||||
vite: 8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
|
||||
vite-hot-client: 2.1.0(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
|
||||
|
||||
vite-hot-client@2.1.0(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)):
|
||||
dependencies:
|
||||
vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
|
||||
|
||||
vite-hot-client@2.1.0(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)):
|
||||
dependencies:
|
||||
vite: 8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
|
||||
@@ -33322,6 +33389,21 @@ snapshots:
|
||||
- tsx
|
||||
- yaml
|
||||
|
||||
vite-plugin-inspect@11.3.3(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)):
|
||||
dependencies:
|
||||
ansis: 4.2.0
|
||||
debug: 4.4.3(supports-color@10.2.2)
|
||||
error-stack-parser-es: 1.0.5
|
||||
ohash: 2.0.11
|
||||
open: 10.2.0
|
||||
perfect-debounce: 2.1.0
|
||||
sirv: 3.0.2
|
||||
unplugin-utils: 0.3.1
|
||||
vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
|
||||
vite-dev-rpc: 1.1.0(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
vite-plugin-inspect@11.3.3(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)):
|
||||
dependencies:
|
||||
ansis: 4.2.0
|
||||
@@ -33353,6 +33435,13 @@ snapshots:
|
||||
- typescript
|
||||
- ws
|
||||
|
||||
vite-plugin-mkcert@2.0.0(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)):
|
||||
dependencies:
|
||||
debug: 4.4.3(supports-color@10.2.2)
|
||||
supports-color: 10.2.2
|
||||
undici: 8.1.0
|
||||
vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
|
||||
|
||||
vite-plugin-mkcert@2.0.0(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)):
|
||||
dependencies:
|
||||
debug: 4.4.3(supports-color@10.2.2)
|
||||
@@ -33371,6 +33460,20 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
vite-plugin-vue-devtools@8.1.1(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(vue@3.5.32(typescript@5.9.3)):
|
||||
dependencies:
|
||||
'@vue/devtools-core': 8.1.1(vue@3.5.32(typescript@5.9.3))
|
||||
'@vue/devtools-kit': 8.1.1
|
||||
'@vue/devtools-shared': 8.1.1
|
||||
sirv: 3.0.2
|
||||
vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
|
||||
vite-plugin-inspect: 11.3.3(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
|
||||
vite-plugin-vue-inspector: 5.3.2(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
|
||||
transitivePeerDependencies:
|
||||
- '@nuxt/kit'
|
||||
- supports-color
|
||||
- vue
|
||||
|
||||
vite-plugin-vue-devtools@8.1.1(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(vue@3.5.32(typescript@5.9.3)):
|
||||
dependencies:
|
||||
'@vue/devtools-core': 8.1.1(vue@3.5.32(typescript@5.9.3))
|
||||
@@ -33385,6 +33488,21 @@ snapshots:
|
||||
- supports-color
|
||||
- vue
|
||||
|
||||
vite-plugin-vue-inspector@5.3.2(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)):
|
||||
dependencies:
|
||||
'@babel/core': 7.29.0
|
||||
'@babel/plugin-proposal-decorators': 7.28.0(@babel/core@7.29.0)
|
||||
'@babel/plugin-syntax-import-attributes': 7.28.6(@babel/core@7.29.0)
|
||||
'@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.29.0)
|
||||
'@babel/plugin-transform-typescript': 7.28.5(@babel/core@7.29.0)
|
||||
'@vue/babel-plugin-jsx': 1.5.0(@babel/core@7.29.0)
|
||||
'@vue/compiler-dom': 3.5.32
|
||||
kolorist: 1.8.0
|
||||
magic-string: 0.30.21
|
||||
vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
vite-plugin-vue-inspector@5.3.2(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)):
|
||||
dependencies:
|
||||
'@babel/core': 7.29.0
|
||||
@@ -33400,6 +33518,16 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
vite-plugin-vue-layouts@0.11.0(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(vue-router@5.0.4(@pinia/colada@1.2.1(pinia@3.0.4(typescript@5.9.3)(vue@3.5.32(typescript@5.9.3)))(vue@3.5.32(typescript@5.9.3)))(@vue/compiler-sfc@3.5.32)(pinia@3.0.4(typescript@5.9.3)(vue@3.5.32(typescript@5.9.3)))(vue@3.5.32(typescript@5.9.3)))(vue@3.5.32(typescript@5.9.3)):
|
||||
dependencies:
|
||||
debug: 4.4.3(supports-color@10.2.2)
|
||||
fast-glob: 3.3.3
|
||||
vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
|
||||
vue: 3.5.32(typescript@5.9.3)
|
||||
vue-router: 5.0.4(@pinia/colada@1.2.1(pinia@3.0.4(typescript@5.9.3)(vue@3.5.32(typescript@5.9.3)))(vue@3.5.32(typescript@5.9.3)))(@vue/compiler-sfc@3.5.32)(pinia@3.0.4(typescript@5.9.3)(vue@3.5.32(typescript@5.9.3)))(vue@3.5.32(typescript@5.9.3))
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
vite-plugin-vue-layouts@0.11.0(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(vue-router@5.0.4(@pinia/colada@1.2.1(pinia@3.0.4(typescript@5.9.3)(vue@3.5.32(typescript@5.9.3)))(vue@3.5.32(typescript@5.9.3)))(@vue/compiler-sfc@3.5.32)(pinia@3.0.4(typescript@5.9.3)(vue@3.5.32(typescript@5.9.3)))(vue@3.5.32(typescript@5.9.3)))(vue@3.5.32(typescript@5.9.3)):
|
||||
dependencies:
|
||||
debug: 4.4.3(supports-color@10.2.2)
|
||||
@@ -33520,7 +33648,7 @@ snapshots:
|
||||
vitest-browser-vue@2.1.0(vitest@4.1.4)(vue@3.5.32(typescript@5.9.3)):
|
||||
dependencies:
|
||||
'@vue/test-utils': 2.4.6
|
||||
vitest: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@25.6.0)(@vitest/browser-playwright@4.1.4)(@vitest/coverage-v8@4.1.4)(jsdom@29.0.2(@noble/hashes@2.0.1)(canvas@3.2.3))(vite@6.4.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
|
||||
vitest: 4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(@vitest/browser-playwright@4.1.4)(@vitest/coverage-v8@4.1.4)(jsdom@29.0.2(@noble/hashes@2.0.1)(canvas@3.2.3))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
|
||||
vue: 3.5.32(typescript@5.9.3)
|
||||
|
||||
vitest@4.1.4(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(@vitest/browser-playwright@4.1.4)(@vitest/coverage-v8@4.1.4)(jsdom@29.0.2(@noble/hashes@2.0.1)(canvas@3.2.3))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)):
|
||||
@@ -33554,37 +33682,6 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- msw
|
||||
|
||||
vitest@4.1.4(@opentelemetry/api@1.9.1)(@types/node@25.6.0)(@vitest/browser-playwright@4.1.4)(@vitest/coverage-v8@4.1.4)(jsdom@29.0.2(@noble/hashes@2.0.1)(canvas@3.2.3))(vite@6.4.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)):
|
||||
dependencies:
|
||||
'@vitest/expect': 4.1.4
|
||||
'@vitest/mocker': 4.1.4(vite@6.4.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
|
||||
'@vitest/pretty-format': 4.1.4
|
||||
'@vitest/runner': 4.1.4
|
||||
'@vitest/snapshot': 4.1.4
|
||||
'@vitest/spy': 4.1.4
|
||||
'@vitest/utils': 4.1.4
|
||||
es-module-lexer: 2.0.0
|
||||
expect-type: 1.3.0
|
||||
magic-string: 0.30.21
|
||||
obug: 2.1.1
|
||||
pathe: 2.0.3
|
||||
picomatch: 4.0.4
|
||||
std-env: 4.1.0
|
||||
tinybench: 2.9.0
|
||||
tinyexec: 1.1.1
|
||||
tinyglobby: 0.2.16
|
||||
tinyrainbow: 3.1.0
|
||||
vite: 6.4.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
|
||||
why-is-node-running: 2.3.0
|
||||
optionalDependencies:
|
||||
'@opentelemetry/api': 1.9.1
|
||||
'@types/node': 25.6.0
|
||||
'@vitest/browser-playwright': 4.1.4(bufferutil@4.1.0)(playwright@1.59.1)(utf-8-validate@5.0.10)(vite@6.4.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.4)
|
||||
'@vitest/coverage-v8': 4.1.4(@vitest/browser@4.1.4)(vitest@4.1.4)
|
||||
jsdom: 29.0.2(@noble/hashes@2.0.1)(canvas@3.2.3)
|
||||
transitivePeerDependencies:
|
||||
- msw
|
||||
|
||||
vitest@4.1.4(@opentelemetry/api@1.9.1)(@types/node@25.6.0)(@vitest/browser-playwright@4.1.4)(@vitest/coverage-v8@4.1.4)(jsdom@29.0.2(@noble/hashes@2.0.1)(canvas@3.2.3))(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)):
|
||||
dependencies:
|
||||
'@vitest/expect': 4.1.4
|
||||
@@ -33697,6 +33794,54 @@ snapshots:
|
||||
- vue-tsc
|
||||
- webpack
|
||||
|
||||
vue-macros@3.1.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@vueuse/core@14.2.1(vue@3.5.32(typescript@5.9.3)))(esbuild@0.27.2)(rolldown@1.0.0-rc.16)(rollup@4.60.1)(typescript@5.9.3)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(vue-tsc@3.2.6(typescript@5.9.3))(vue@3.5.32(typescript@5.9.3)):
|
||||
dependencies:
|
||||
'@vue-macros/better-define': 3.1.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(vue@3.5.32(typescript@5.9.3))
|
||||
'@vue-macros/boolean-prop': 3.1.2(vue@3.5.32(typescript@5.9.3))
|
||||
'@vue-macros/chain-call': 3.1.2(vue@3.5.32(typescript@5.9.3))
|
||||
'@vue-macros/common': 3.1.2(vue@3.5.32(typescript@5.9.3))
|
||||
'@vue-macros/config': 3.1.2(vue@3.5.32(typescript@5.9.3))
|
||||
'@vue-macros/define-emit': 3.1.2(vue@3.5.32(typescript@5.9.3))
|
||||
'@vue-macros/define-models': 3.1.2(@vueuse/core@14.2.1(vue@3.5.32(typescript@5.9.3)))(vue@3.5.32(typescript@5.9.3))
|
||||
'@vue-macros/define-prop': 3.1.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(vue@3.5.32(typescript@5.9.3))
|
||||
'@vue-macros/define-props': 3.1.2(@vue-macros/reactivity-transform@3.1.2(vue@3.5.32(typescript@5.9.3)))(vue@3.5.32(typescript@5.9.3))
|
||||
'@vue-macros/define-props-refs': 3.1.2(vue@3.5.32(typescript@5.9.3))
|
||||
'@vue-macros/define-render': 3.1.2(vue@3.5.32(typescript@5.9.3))
|
||||
'@vue-macros/define-slots': 3.1.2(vue@3.5.32(typescript@5.9.3))
|
||||
'@vue-macros/define-stylex': 3.1.2(vue@3.5.32(typescript@5.9.3))
|
||||
'@vue-macros/devtools': 3.1.2(typescript@5.9.3)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
|
||||
'@vue-macros/export-expose': 3.1.2(vue@3.5.32(typescript@5.9.3))
|
||||
'@vue-macros/export-props': 3.1.2(vue@3.5.32(typescript@5.9.3))
|
||||
'@vue-macros/export-render': 3.1.2(vue@3.5.32(typescript@5.9.3))
|
||||
'@vue-macros/hoist-static': 3.1.2(vue@3.5.32(typescript@5.9.3))
|
||||
'@vue-macros/jsx-directive': 3.1.2(typescript@5.9.3)
|
||||
'@vue-macros/named-template': 3.1.2(vue@3.5.32(typescript@5.9.3))
|
||||
'@vue-macros/reactivity-transform': 3.1.2(vue@3.5.32(typescript@5.9.3))
|
||||
'@vue-macros/script-lang': 3.1.2(vue@3.5.32(typescript@5.9.3))
|
||||
'@vue-macros/setup-block': 3.1.2(vue@3.5.32(typescript@5.9.3))
|
||||
'@vue-macros/setup-component': 3.1.2(vue@3.5.32(typescript@5.9.3))
|
||||
'@vue-macros/setup-sfc': 3.1.2(vue@3.5.32(typescript@5.9.3))
|
||||
'@vue-macros/short-bind': 3.1.2(vue@3.5.32(typescript@5.9.3))
|
||||
'@vue-macros/short-emits': 3.1.2(vue@3.5.32(typescript@5.9.3))
|
||||
'@vue-macros/short-vmodel': 3.1.2(vue@3.5.32(typescript@5.9.3))
|
||||
'@vue-macros/volar': 3.1.2(typescript@5.9.3)(vue-tsc@3.2.6(typescript@5.9.3))(vue@3.5.32(typescript@5.9.3))
|
||||
unplugin: 2.3.11
|
||||
unplugin-combine: 2.3.0(esbuild@0.27.2)(rolldown@1.0.0-rc.16)(rollup@4.60.1)(unplugin@2.3.11)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
|
||||
unplugin-vue-define-options: 3.1.2(vue@3.5.32(typescript@5.9.3))
|
||||
vue: 3.5.32(typescript@5.9.3)
|
||||
transitivePeerDependencies:
|
||||
- '@emnapi/core'
|
||||
- '@emnapi/runtime'
|
||||
- '@rspack/core'
|
||||
- '@vueuse/core'
|
||||
- esbuild
|
||||
- rolldown
|
||||
- rollup
|
||||
- typescript
|
||||
- vite
|
||||
- vue-tsc
|
||||
- webpack
|
||||
|
||||
vue-macros@3.1.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@vueuse/core@14.2.1(vue@3.5.32(typescript@5.9.3)))(esbuild@0.27.2)(rolldown@1.0.0-rc.16)(rollup@4.60.1)(typescript@5.9.3)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(vue-tsc@3.2.6(typescript@5.9.3))(vue@3.5.32(typescript@5.9.3)):
|
||||
dependencies:
|
||||
'@vue-macros/better-define': 3.1.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(vue@3.5.32(typescript@5.9.3))
|
||||
|
||||
Reference in New Issue
Block a user