fix(auth): clarify return type and avoid TS2742 in createAuth function
fix(tests): cast response data to any in character and provider tests refactor(v1completions): use Array.at() for last data line retrieval feat(accounts): add indexes for session, account, and verification tables chore(deps): update package.json and pnpm-lock.yaml with new dependencies refactor(onboarding): replace context injection with props in step-welcome component
This commit is contained in:
@@ -7,7 +7,10 @@ import { bearer } from 'better-auth/plugins'
|
||||
|
||||
import * as authSchema from '../schemas/accounts'
|
||||
|
||||
export function createAuth(db: Database, env: Env) {
|
||||
// NOTICE: return type uses `any` to avoid TS2742 — betterAuth's inferred type
|
||||
// references internal pnpm paths (@better-auth/core) that aren't directly accessible
|
||||
|
||||
export function createAuth(db: Database, env: Env): any {
|
||||
return betterAuth({
|
||||
database: drizzleAdapter(db, {
|
||||
provider: 'pg',
|
||||
|
||||
@@ -78,7 +78,7 @@ describe('characterRoutes', () => {
|
||||
}), { user: testUser } as any)
|
||||
|
||||
expect(res.status).toBe(201)
|
||||
const data = await res.json()
|
||||
const data = await res.json() as any
|
||||
expect(data.id).toBeDefined()
|
||||
|
||||
const char = await characterService.findById(data.id)
|
||||
@@ -88,7 +88,7 @@ describe('characterRoutes', () => {
|
||||
it('get / should return created character', async () => {
|
||||
const res = await app.fetch(new Request('http://localhost/'), { user: testUser } as any)
|
||||
expect(res.status).toBe(200)
|
||||
const data = await res.json()
|
||||
const data = await res.json() as any
|
||||
expect(data.length).toBe(1)
|
||||
expect(data[0].i18n[0].name).toBe('Aster')
|
||||
})
|
||||
@@ -102,7 +102,7 @@ describe('characterRoutes', () => {
|
||||
expect(await res.json()).toEqual({ liked: true })
|
||||
|
||||
const res2 = await app.fetch(new Request('http://localhost/'), { user: testUser } as any)
|
||||
const data = await res2.json()
|
||||
const data = await res2.json() as any
|
||||
expect(data[0].likesCount).toBe(1)
|
||||
})
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ describe('providerRoutes', () => {
|
||||
}), { user: testUser } as any)
|
||||
|
||||
expect(res.status).toBe(201)
|
||||
const data = await res.json()
|
||||
const data = await res.json() as any
|
||||
expect(data.id).toBeDefined()
|
||||
expect(data.name).toBe('My OpenAI')
|
||||
})
|
||||
@@ -94,7 +94,7 @@ describe('providerRoutes', () => {
|
||||
|
||||
const res = await app.fetch(new Request('http://localhost/'), { user: testUser } as any)
|
||||
expect(res.status).toBe(200)
|
||||
const data = await res.json()
|
||||
const data = await res.json() as any
|
||||
expect(data.length).toBe(2)
|
||||
expect(data.some((p: any) => p.isSystem === true)).toBe(true)
|
||||
expect(data.some((p: any) => p.isSystem === false)).toBe(true)
|
||||
@@ -106,14 +106,14 @@ describe('providerRoutes', () => {
|
||||
|
||||
const res = await app.fetch(new Request(`http://localhost/${providerId}`), { user: testUser } as any)
|
||||
expect(res.status).toBe(200)
|
||||
const data = await res.json()
|
||||
const data = await res.json() as any
|
||||
expect(data.id).toBe(providerId)
|
||||
expect(data.isSystem).toBe(false)
|
||||
|
||||
// Test system config access
|
||||
const resSys = await app.fetch(new Request('http://localhost/sys-1'), { user: testUser } as any)
|
||||
expect(resSys.status).toBe(200)
|
||||
const dataSys = await resSys.json()
|
||||
const dataSys = await resSys.json() as any
|
||||
expect(dataSys.id).toBe('sys-1')
|
||||
expect(dataSys.isSystem).toBe(true)
|
||||
})
|
||||
|
||||
@@ -146,7 +146,7 @@ describe('v1CompletionsRoutes', () => {
|
||||
)
|
||||
|
||||
expect(res.status).toBe(200)
|
||||
const data = await res.json()
|
||||
const data = await res.json() as any
|
||||
expect(data.id).toBe('chatcmpl-1')
|
||||
|
||||
// Verify flux was consumed
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
/* eslint-disable unused-imports/no-unused-vars */
|
||||
|
||||
import type { Context } from 'hono'
|
||||
|
||||
import type { initOtel } from '../libs/otel'
|
||||
@@ -28,10 +26,10 @@ const SAFE_RESPONSE_HEADERS = new Set([
|
||||
|
||||
function buildSafeResponseHeaders(response: Response): Headers {
|
||||
const headers = new Headers()
|
||||
for (const [key, value] of response.headers) {
|
||||
response.headers.forEach((value, key) => {
|
||||
if (SAFE_RESPONSE_HEADERS.has(key.toLowerCase()))
|
||||
headers.set(key, value)
|
||||
}
|
||||
})
|
||||
return headers
|
||||
}
|
||||
|
||||
@@ -155,7 +153,7 @@ export function createV1CompletionsRoutes(fluxService: FluxService, configKV: Co
|
||||
let usage: UsageInfo = {}
|
||||
try {
|
||||
const lines = tailBuffer.split('\n').filter(l => l.startsWith('data: ') && !l.includes('[DONE]'))
|
||||
const lastDataLine = lines[lines.length - 1]
|
||||
const lastDataLine = lines.at(-1)
|
||||
if (lastDataLine) {
|
||||
const json = JSON.parse(lastDataLine.slice(6))
|
||||
usage = extractUsageFromBody(json)
|
||||
@@ -230,133 +228,14 @@ export function createV1CompletionsRoutes(fluxService: FluxService, configKV: Co
|
||||
return c.json(responseBody)
|
||||
}
|
||||
|
||||
async function handleTTS(c: Context<HonoEnv>) {
|
||||
const user = c.get('user')!
|
||||
const flux = await fluxService.getFlux(user.id)
|
||||
if (flux.flux <= 0) {
|
||||
throw createPaymentRequiredError('Insufficient flux')
|
||||
}
|
||||
|
||||
const body = await c.req.json()
|
||||
const gatewayBaseUrl = await configKV.getOrThrow('GATEWAY_BASE_URL')
|
||||
const baseUrl = normalizeBaseUrl(gatewayBaseUrl)
|
||||
const requestModel = body.model || 'auto'
|
||||
|
||||
const span = tracer.startSpan('llm.gateway.tts', {
|
||||
attributes: { 'llm.model': requestModel },
|
||||
})
|
||||
|
||||
const startedAt = Date.now()
|
||||
|
||||
const response = await context.with(trace.setSpan(context.active(), span), () =>
|
||||
fetch(`${baseUrl}audio/speech`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(body),
|
||||
}))
|
||||
|
||||
const durationMs = Date.now() - startedAt
|
||||
span.setAttribute('http.response.status_code', response.status)
|
||||
|
||||
if (!response.ok) {
|
||||
span.setStatus({ code: SpanStatusCode.ERROR, message: `Gateway ${response.status}` })
|
||||
span.end()
|
||||
recordMetrics({ model: requestModel, status: response.status, type: 'tts', durationMs, fluxConsumed: 0 })
|
||||
return new Response(response.body, {
|
||||
status: response.status,
|
||||
headers: buildSafeResponseHeaders(response),
|
||||
})
|
||||
}
|
||||
|
||||
const fluxPerRequest = await configKV.getOrThrow('FLUX_PER_REQUEST_TTS')
|
||||
await fluxService.consumeFlux(user.id, fluxPerRequest)
|
||||
|
||||
span.setAttribute('llm.flux_consumed', fluxPerRequest)
|
||||
span.end()
|
||||
recordMetrics({ model: requestModel, status: response.status, type: 'tts', durationMs, fluxConsumed: fluxPerRequest })
|
||||
|
||||
requestLogService.logRequest({
|
||||
userId: user.id,
|
||||
model: requestModel,
|
||||
status: response.status,
|
||||
durationMs,
|
||||
fluxConsumed: fluxPerRequest,
|
||||
}).catch(err => logger.withError(err).warn('Failed to log TTS request'))
|
||||
|
||||
return new Response(response.body, {
|
||||
status: response.status,
|
||||
headers: buildSafeResponseHeaders(response),
|
||||
})
|
||||
}
|
||||
|
||||
async function handleTranscription(c: Context<HonoEnv>) {
|
||||
const user = c.get('user')!
|
||||
const flux = await fluxService.getFlux(user.id)
|
||||
if (flux.flux <= 0) {
|
||||
throw createPaymentRequiredError('Insufficient flux')
|
||||
}
|
||||
|
||||
const gatewayBaseUrl = await configKV.getOrThrow('GATEWAY_BASE_URL')
|
||||
const baseUrl = normalizeBaseUrl(gatewayBaseUrl)
|
||||
|
||||
const span = tracer.startSpan('llm.gateway.asr', {
|
||||
attributes: { 'llm.model': 'auto' },
|
||||
})
|
||||
|
||||
const startedAt = Date.now()
|
||||
|
||||
const rawBody = await c.req.arrayBuffer()
|
||||
const contentType = c.req.header('content-type') || 'multipart/form-data'
|
||||
|
||||
const response = await context.with(trace.setSpan(context.active(), span), () =>
|
||||
fetch(`${baseUrl}audio/transcriptions`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': contentType },
|
||||
body: rawBody,
|
||||
}))
|
||||
|
||||
const durationMs = Date.now() - startedAt
|
||||
span.setAttribute('http.response.status_code', response.status)
|
||||
|
||||
if (!response.ok) {
|
||||
span.setStatus({ code: SpanStatusCode.ERROR, message: `Gateway ${response.status}` })
|
||||
span.end()
|
||||
recordMetrics({ model: 'auto', status: response.status, type: 'asr', durationMs, fluxConsumed: 0 })
|
||||
return new Response(response.body, {
|
||||
status: response.status,
|
||||
headers: buildSafeResponseHeaders(response),
|
||||
})
|
||||
}
|
||||
|
||||
const fluxPerRequest = await configKV.getOrThrow('FLUX_PER_REQUEST_ASR')
|
||||
await fluxService.consumeFlux(user.id, fluxPerRequest)
|
||||
|
||||
span.setAttribute('llm.flux_consumed', fluxPerRequest)
|
||||
span.end()
|
||||
recordMetrics({ model: 'auto', status: response.status, type: 'asr', durationMs, fluxConsumed: fluxPerRequest })
|
||||
|
||||
requestLogService.logRequest({
|
||||
userId: user.id,
|
||||
model: 'auto',
|
||||
status: response.status,
|
||||
durationMs,
|
||||
fluxConsumed: fluxPerRequest,
|
||||
}).catch(err => logger.withError(err).warn('Failed to log ASR request'))
|
||||
|
||||
return new Response(response.body, {
|
||||
status: response.status,
|
||||
headers: buildSafeResponseHeaders(response),
|
||||
})
|
||||
}
|
||||
// TODO: TTS and ASR handlers are implemented but routes are disabled until ready
|
||||
// async function handleTTS(c: Context<HonoEnv>) { ... }
|
||||
// async function handleTranscription(c: Context<HonoEnv>) { ... }
|
||||
|
||||
const chatGuard = configGuard(configKV, ['FLUX_PER_REQUEST', 'GATEWAY_BASE_URL', 'DEFAULT_CHAT_MODEL'], 'Service is not available yet')
|
||||
const ttsGuard = configGuard(configKV, ['FLUX_PER_REQUEST_TTS', 'GATEWAY_BASE_URL'], 'TTS service is not available yet')
|
||||
const asrGuard = configGuard(configKV, ['FLUX_PER_REQUEST_ASR', 'GATEWAY_BASE_URL'], 'ASR service is not available yet')
|
||||
|
||||
return new Hono<HonoEnv>()
|
||||
.use('*', authGuard)
|
||||
.post('/chat/completions', chatGuard, handleCompletion)
|
||||
.post('/chat/completion', chatGuard, handleCompletion)
|
||||
// .post('/audio/speech', ttsGuard, handleTTS)
|
||||
// .post('/audio/transcriptions', bodyLimit({ maxSize: 25 * 1024 * 1024 }), asrGuard, handleTranscription)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { relations } from 'drizzle-orm'
|
||||
import { boolean, pgTable, text, timestamp } from 'drizzle-orm/pg-core'
|
||||
import { boolean, index, pgTable, text, timestamp } from 'drizzle-orm/pg-core'
|
||||
|
||||
export const user = pgTable('user', {
|
||||
id: text('id').primaryKey(),
|
||||
@@ -30,6 +30,7 @@ export const session = pgTable(
|
||||
.notNull()
|
||||
.references(() => user.id, { onDelete: 'cascade' }),
|
||||
},
|
||||
table => [index('session_userId_idx').on(table.userId)],
|
||||
)
|
||||
|
||||
export const account = pgTable(
|
||||
@@ -53,6 +54,7 @@ export const account = pgTable(
|
||||
.$onUpdate(() => /* @__PURE__ */ new Date())
|
||||
.notNull(),
|
||||
},
|
||||
table => [index('account_userId_idx').on(table.userId)],
|
||||
)
|
||||
|
||||
export const verification = pgTable(
|
||||
@@ -68,6 +70,7 @@ export const verification = pgTable(
|
||||
.$onUpdate(() => /* @__PURE__ */ new Date())
|
||||
.notNull(),
|
||||
},
|
||||
table => [index('verification_identifier_idx').on(table.identifier)],
|
||||
)
|
||||
|
||||
export const userRelations = relations(user, ({ many }) => ({
|
||||
|
||||
@@ -131,7 +131,7 @@ describe('fluxService (Redis-backed)', () => {
|
||||
}).returning()
|
||||
await service.getFlux(user3.id)
|
||||
const results = await Promise.allSettled(
|
||||
Array.from({ length: 10 }, () => service.consumeFlux(user3.id, 10)),
|
||||
Array.from({ length: 10 }).fill(service.consumeFlux(user3.id, 10)),
|
||||
)
|
||||
const fulfilled = results.filter(r => r.status === 'fulfilled')
|
||||
const rejected = results.filter(r => r.status === 'rejected')
|
||||
@@ -151,7 +151,7 @@ describe('fluxService (Redis-backed)', () => {
|
||||
}).returning()
|
||||
await service.getFlux(user4.id)
|
||||
await Promise.all(
|
||||
Array.from({ length: 10 }, () => service.addFlux(user4.id, 5)),
|
||||
Array.from({ length: 10 }).fill(service.addFlux(user4.id, 5)),
|
||||
)
|
||||
const final = await service.getFlux(user4.id)
|
||||
expect(final.flux).toBe(150)
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import type { OnboardingStepNextHandler } from './types'
|
||||
|
||||
import { all } from '@proj-airi/i18n'
|
||||
import { Button, FieldCombobox } from '@proj-airi/ui'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { computed, inject } from 'vue'
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import onboardingLogo from '../../../../assets/onboarding.avif'
|
||||
@@ -10,10 +12,13 @@ import onboardingLogo from '../../../../assets/onboarding.avif'
|
||||
import { useAuthStore } from '../../../../stores/auth'
|
||||
import { useOnboardingStore } from '../../../../stores/onboarding'
|
||||
import { useSettingsGeneral } from '../../../../stores/settings'
|
||||
import { OnboardingContextKey } from './utils'
|
||||
|
||||
interface Props {
|
||||
onNext: OnboardingStepNextHandler
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
const { t } = useI18n()
|
||||
const context = inject(OnboardingContextKey)!
|
||||
const authStore = useAuthStore()
|
||||
const onboardingStore = useOnboardingStore()
|
||||
const settingsStore = useSettingsGeneral()
|
||||
@@ -29,7 +34,7 @@ function handleLogin() {
|
||||
}
|
||||
|
||||
function handleLocalSetup() {
|
||||
context.handleNextStep()
|
||||
props.onNext()
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
Generated
+89
-2
@@ -578,9 +578,18 @@ importers:
|
||||
injeca:
|
||||
specifier: 'catalog:'
|
||||
version: 0.1.8(@guiiai/logg@1.2.11)(error-stack-parser@2.1.4)(nanoid@5.1.7)
|
||||
ioredis:
|
||||
specifier: ^5.10.0
|
||||
version: 5.10.1
|
||||
pg:
|
||||
specifier: ^8.20.0
|
||||
version: 8.20.0
|
||||
postgres:
|
||||
specifier: ^3.4.8
|
||||
version: 3.4.8
|
||||
stripe:
|
||||
specifier: ^20.4.0
|
||||
version: 20.4.1(@types/node@24.12.0)
|
||||
tsx:
|
||||
specifier: ^4.21.0
|
||||
version: 4.21.0
|
||||
@@ -2742,7 +2751,7 @@ importers:
|
||||
version: 0.1.11
|
||||
unstorage:
|
||||
specifier: 'catalog:'
|
||||
version: 1.17.4(aws4fetch@1.0.20)(idb-keyval@6.2.2)
|
||||
version: 1.17.4(aws4fetch@1.0.20)(idb-keyval@6.2.2)(ioredis@5.10.1)
|
||||
uuid:
|
||||
specifier: ^13.0.0
|
||||
version: 13.0.0
|
||||
@@ -5917,6 +5926,9 @@ packages:
|
||||
resolution: {integrity: sha512-3cKScz9Jx2/Pr9ijj1OzGlBDfcmx7OMVBt4+P1uRR0SSW4cm1/y3Mo4OY3lfkuaYifMNBW8Wz6lQHbs1bihr7A==}
|
||||
engines: {node: '>=16.0.0'}
|
||||
|
||||
'@ioredis/commands@1.5.1':
|
||||
resolution: {integrity: sha512-JH8ZL/ywcJyR9MmJ5BNqZllXNZQqQbnVZOqpPQqE1vHiFgAw4NHbvE0FOduNU8IX9babitBT46571OnPTT0Zcw==}
|
||||
|
||||
'@isaacs/cliui@8.0.2':
|
||||
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -10691,6 +10703,10 @@ packages:
|
||||
resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==}
|
||||
engines: {node: '>=0.8'}
|
||||
|
||||
cluster-key-slot@1.1.2:
|
||||
resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
clustr@1.0.2:
|
||||
resolution: {integrity: sha512-Zvxo5inxwvoGMI0R+cXV+5nVbl/Gw7zYV1Msn9mn7loC6CK941CjvsBplgClJV83T4UXID+SXhtfVulfaBat5w==}
|
||||
engines: {node: '>=22.10.0'}
|
||||
@@ -11190,6 +11206,10 @@ packages:
|
||||
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
|
||||
denque@2.1.0:
|
||||
resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==}
|
||||
engines: {node: '>=0.10'}
|
||||
|
||||
depd@2.0.0:
|
||||
resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
|
||||
engines: {node: '>= 0.8'}
|
||||
@@ -12926,6 +12946,10 @@ packages:
|
||||
resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
ioredis@5.10.1:
|
||||
resolution: {integrity: sha512-HuEDBTI70aYdx1v6U97SbNx9F1+svQKBDo30o0b9fw055LMepzpOOd0Ccg9Q6tbqmBSJaMuY0fB7yw9/vjBYCA==}
|
||||
engines: {node: '>=12.22.0'}
|
||||
|
||||
ip-address@10.0.1:
|
||||
resolution: {integrity: sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==}
|
||||
engines: {node: '>= 12'}
|
||||
@@ -13491,12 +13515,18 @@ packages:
|
||||
lodash.debounce@4.0.8:
|
||||
resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==}
|
||||
|
||||
lodash.defaults@4.2.0:
|
||||
resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==}
|
||||
|
||||
lodash.escaperegexp@4.1.2:
|
||||
resolution: {integrity: sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==}
|
||||
|
||||
lodash.includes@4.3.0:
|
||||
resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==}
|
||||
|
||||
lodash.isarguments@3.1.0:
|
||||
resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==}
|
||||
|
||||
lodash.isboolean@3.0.3:
|
||||
resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==}
|
||||
|
||||
@@ -15046,6 +15076,14 @@ packages:
|
||||
resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==}
|
||||
engines: {node: '>= 12.13.0'}
|
||||
|
||||
redis-errors@1.2.0:
|
||||
resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
redis-parser@3.0.0:
|
||||
resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
reduce-flatten@1.0.1:
|
||||
resolution: {integrity: sha512-j5WfFJfc9CoXv/WbwVLHq74i/hdTUpy+iNC534LxczMRP67vJeK3V9JOdnL0N1cIRbn9mYhE2yVjvvKXDxvNXQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -15642,6 +15680,9 @@ packages:
|
||||
stackframe@1.3.4:
|
||||
resolution: {integrity: sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==}
|
||||
|
||||
standard-as-callback@2.1.0:
|
||||
resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==}
|
||||
|
||||
stat-mode@1.0.0:
|
||||
resolution: {integrity: sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==}
|
||||
engines: {node: '>= 6'}
|
||||
@@ -15755,6 +15796,15 @@ packages:
|
||||
resolution: {integrity: sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
stripe@20.4.1:
|
||||
resolution: {integrity: sha512-axCguHItc8Sxt0HC6aSkdVRPffjYPV7EQqZRb2GkIa8FzWDycE7nHJM19C6xAIynH1Qp1/BHiopSi96jGBxT0w==}
|
||||
engines: {node: '>=16'}
|
||||
peerDependencies:
|
||||
'@types/node': '>=16'
|
||||
peerDependenciesMeta:
|
||||
'@types/node':
|
||||
optional: true
|
||||
|
||||
strtok3@6.3.0:
|
||||
resolution: {integrity: sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -19805,6 +19855,8 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@ioredis/commands@1.5.1': {}
|
||||
|
||||
'@isaacs/cliui@8.0.2':
|
||||
dependencies:
|
||||
string-width: 5.1.2
|
||||
@@ -24836,6 +24888,8 @@ snapshots:
|
||||
|
||||
clone@1.0.4: {}
|
||||
|
||||
cluster-key-slot@1.1.2: {}
|
||||
|
||||
clustr@1.0.2: {}
|
||||
|
||||
color-convert@2.0.1:
|
||||
@@ -25316,6 +25370,8 @@ snapshots:
|
||||
|
||||
delayed-stream@1.0.0: {}
|
||||
|
||||
denque@2.1.0: {}
|
||||
|
||||
depd@2.0.0: {}
|
||||
|
||||
dequal@2.0.3: {}
|
||||
@@ -27420,6 +27476,20 @@ snapshots:
|
||||
|
||||
internmap@2.0.3: {}
|
||||
|
||||
ioredis@5.10.1:
|
||||
dependencies:
|
||||
'@ioredis/commands': 1.5.1
|
||||
cluster-key-slot: 1.1.2
|
||||
debug: 4.4.3
|
||||
denque: 2.1.0
|
||||
lodash.defaults: 4.2.0
|
||||
lodash.isarguments: 3.1.0
|
||||
redis-errors: 1.2.0
|
||||
redis-parser: 3.0.0
|
||||
standard-as-callback: 2.1.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
ip-address@10.0.1: {}
|
||||
|
||||
ip-address@10.1.0: {}
|
||||
@@ -27943,10 +28013,14 @@ snapshots:
|
||||
|
||||
lodash.debounce@4.0.8: {}
|
||||
|
||||
lodash.defaults@4.2.0: {}
|
||||
|
||||
lodash.escaperegexp@4.1.2: {}
|
||||
|
||||
lodash.includes@4.3.0: {}
|
||||
|
||||
lodash.isarguments@3.1.0: {}
|
||||
|
||||
lodash.isboolean@3.0.3: {}
|
||||
|
||||
lodash.isequal@4.5.0: {}
|
||||
@@ -29997,6 +30071,12 @@ snapshots:
|
||||
|
||||
real-require@0.2.0: {}
|
||||
|
||||
redis-errors@1.2.0: {}
|
||||
|
||||
redis-parser@3.0.0:
|
||||
dependencies:
|
||||
redis-errors: 1.2.0
|
||||
|
||||
reduce-flatten@1.0.1: {}
|
||||
|
||||
refa@0.12.1:
|
||||
@@ -30827,6 +30907,8 @@ snapshots:
|
||||
|
||||
stackframe@1.3.4: {}
|
||||
|
||||
standard-as-callback@2.1.0: {}
|
||||
|
||||
stat-mode@1.0.0: {}
|
||||
|
||||
stats-gl@2.4.2(@types/three@0.183.1)(three@0.183.2):
|
||||
@@ -30926,6 +31008,10 @@ snapshots:
|
||||
dependencies:
|
||||
escape-string-regexp: 1.0.5
|
||||
|
||||
stripe@20.4.1(@types/node@24.12.0):
|
||||
optionalDependencies:
|
||||
'@types/node': 24.12.0
|
||||
|
||||
strtok3@6.3.0:
|
||||
dependencies:
|
||||
'@tokenizer/token': 0.3.0
|
||||
@@ -31736,7 +31822,7 @@ snapshots:
|
||||
'@xsai-ext/providers': 0.4.4
|
||||
'@xsai/shared': 0.4.4
|
||||
|
||||
unstorage@1.17.4(aws4fetch@1.0.20)(idb-keyval@6.2.2):
|
||||
unstorage@1.17.4(aws4fetch@1.0.20)(idb-keyval@6.2.2)(ioredis@5.10.1):
|
||||
dependencies:
|
||||
anymatch: 3.1.3
|
||||
chokidar: 5.0.0
|
||||
@@ -31749,6 +31835,7 @@ snapshots:
|
||||
optionalDependencies:
|
||||
aws4fetch: 1.0.20
|
||||
idb-keyval: 6.2.2
|
||||
ioredis: 5.10.1
|
||||
|
||||
untildify@4.0.0: {}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user