chore(server, stage-*): resolve type issue
This commit is contained in:
@@ -41,6 +41,7 @@ export function createCharacterRoutes(characterService: CharacterService) {
|
||||
throw createBadRequestError('Invalid Request', 'INVALID_REQUEST', result.issues)
|
||||
}
|
||||
|
||||
// @ts-expect-error - TODO: Fix this
|
||||
const character = await characterService.create({
|
||||
...result.output,
|
||||
character: {
|
||||
@@ -48,7 +49,7 @@ export function createCharacterRoutes(characterService: CharacterService) {
|
||||
ownerId: user.id,
|
||||
creatorId: user.id,
|
||||
},
|
||||
} as any)
|
||||
})
|
||||
|
||||
return c.json(character, 201)
|
||||
})
|
||||
@@ -64,7 +65,7 @@ export function createCharacterRoutes(characterService: CharacterService) {
|
||||
throw createBadRequestError('Invalid Request', 'INVALID_REQUEST', result.issues)
|
||||
}
|
||||
|
||||
const existing = await characterService.findById(id, { withRelations: false })
|
||||
const existing = await characterService.findById(id)
|
||||
if (!existing)
|
||||
throw createNotFoundError()
|
||||
if (existing.ownerId !== user.id)
|
||||
@@ -78,7 +79,7 @@ export function createCharacterRoutes(characterService: CharacterService) {
|
||||
const user = c.get('user')!
|
||||
|
||||
const id = c.req.param('id')
|
||||
const existing = await characterService.findById(id, { withRelations: false })
|
||||
const existing = await characterService.findById(id)
|
||||
if (!existing)
|
||||
throw createNotFoundError()
|
||||
if (existing.ownerId !== user.id)
|
||||
|
||||
@@ -40,7 +40,7 @@ export function createProviderRoutes(providerService: ProviderService) {
|
||||
const provider = await providerService.createUserConfig({
|
||||
...result.output,
|
||||
ownerId: user.id,
|
||||
} as any)
|
||||
})
|
||||
|
||||
return c.json(provider, 201)
|
||||
})
|
||||
|
||||
@@ -8,23 +8,21 @@ import * as userCharacterSchema from '../schemas/user-character'
|
||||
|
||||
export function createCharacterService(db: Database<typeof fullSchema>) {
|
||||
return {
|
||||
async findById(id: string, options: { withRelations?: boolean } = { withRelations: true }) {
|
||||
async findById(id: string) {
|
||||
return await db.query.character.findFirst({
|
||||
where: and(
|
||||
eq(schema.character.id, id),
|
||||
isNull(schema.character.deletedAt),
|
||||
),
|
||||
with: options.withRelations
|
||||
? {
|
||||
capabilities: true,
|
||||
avatarModels: true,
|
||||
i18n: true,
|
||||
prompts: true,
|
||||
likes: true,
|
||||
bookmarks: true,
|
||||
cover: true,
|
||||
}
|
||||
: undefined,
|
||||
with: {
|
||||
capabilities: true,
|
||||
avatarModels: true,
|
||||
i18n: true,
|
||||
prompts: true,
|
||||
likes: true,
|
||||
bookmarks: true,
|
||||
cover: true,
|
||||
},
|
||||
})
|
||||
},
|
||||
|
||||
@@ -44,18 +42,16 @@ export function createCharacterService(db: Database<typeof fullSchema>) {
|
||||
})
|
||||
},
|
||||
|
||||
async findAll(options: { withRelations?: boolean } = { withRelations: true }) {
|
||||
async findAll() {
|
||||
return await db.query.character.findMany({
|
||||
where: isNull(schema.character.deletedAt),
|
||||
with: options.withRelations
|
||||
? {
|
||||
i18n: true,
|
||||
capabilities: true,
|
||||
likes: true,
|
||||
bookmarks: true,
|
||||
cover: true,
|
||||
}
|
||||
: undefined,
|
||||
with: {
|
||||
i18n: true,
|
||||
capabilities: true,
|
||||
likes: true,
|
||||
bookmarks: true,
|
||||
cover: true,
|
||||
},
|
||||
})
|
||||
},
|
||||
|
||||
@@ -150,30 +146,30 @@ export function createCharacterService(db: Database<typeof fullSchema>) {
|
||||
await tx.insert(schema.characterCovers).values({
|
||||
...data.cover,
|
||||
characterId: inserted.id,
|
||||
} as schema.NewCharacterCover)
|
||||
})
|
||||
}
|
||||
|
||||
if (data.capabilities?.length) {
|
||||
await tx.insert(schema.characterCapabilities).values(
|
||||
data.capabilities.map(c => ({ ...c, characterId: inserted.id }) as schema.NewCharacterCapability),
|
||||
data.capabilities.map(c => ({ ...c, characterId: inserted.id })),
|
||||
)
|
||||
}
|
||||
|
||||
if (data.avatarModels?.length) {
|
||||
await tx.insert(schema.avatarModel).values(
|
||||
data.avatarModels.map(a => ({ ...a, characterId: inserted.id }) as schema.NewAvatarModel),
|
||||
data.avatarModels.map(a => ({ ...a, characterId: inserted.id })),
|
||||
)
|
||||
}
|
||||
|
||||
if (data.i18n?.length) {
|
||||
await tx.insert(schema.characterI18n).values(
|
||||
data.i18n.map(i => ({ ...i, characterId: inserted.id }) as schema.NewCharacterI18n),
|
||||
data.i18n.map(i => ({ ...i, characterId: inserted.id })),
|
||||
)
|
||||
}
|
||||
|
||||
if (data.prompts?.length) {
|
||||
await tx.insert(schema.characterPrompts).values(
|
||||
data.prompts.map(p => ({ ...p, characterId: inserted.id }) as schema.NewCharacterPrompt),
|
||||
data.prompts.map(p => ({ ...p, characterId: inserted.id })),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import CharacterDialog from './components/CharacterDialog.vue'
|
||||
import CharacterItem from './components/CharacterItem.vue'
|
||||
|
||||
const characterStore = useCharacterStore()
|
||||
const { characters, isLoading } = storeToRefs(characterStore)
|
||||
const { characters } = storeToRefs(characterStore)
|
||||
|
||||
// Fetch on mount
|
||||
onMounted(() => {
|
||||
@@ -22,7 +22,7 @@ const searchQuery = ref('')
|
||||
const filteredCharacters = computed(() => {
|
||||
const query = searchQuery.value.toLowerCase()
|
||||
return Array.from(characters.value.values()).filter((char) => {
|
||||
const i18n = char.i18n.find(i => i.language === 'en') || char.i18n[0]
|
||||
const i18n = char.i18n?.find(i => i.language === 'en') || char.i18n?.[0]
|
||||
return i18n?.name.toLowerCase().includes(query) || i18n?.description.toLowerCase().includes(query)
|
||||
})
|
||||
})
|
||||
@@ -87,7 +87,7 @@ function handleActivate(char: Character) {
|
||||
</div>
|
||||
|
||||
<!-- Content -->
|
||||
<div v-if="isLoading && characters.size === 0" class="flex flex-1 items-center justify-center">
|
||||
<div v-if="characters.size === 0" class="flex flex-1 items-center justify-center">
|
||||
<div class="i-svg-spinners:90-ring-with-bg text-4xl text-primary-500" />
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import type { Character, CreateCharacterPayload, UpdateCharacterPayload } from '../types/character'
|
||||
|
||||
import { defineStore } from 'pinia'
|
||||
import { parse } from 'valibot'
|
||||
import { ref } from 'vue'
|
||||
|
||||
import { client } from '../composables/api'
|
||||
import { useAsyncState } from '../composables/use-async-state'
|
||||
import { CharacterWithRelationsSchema } from '../types/character'
|
||||
|
||||
export const useCharacterStore = defineStore('characters', () => {
|
||||
const characters = ref<Map<string, Character>>(new Map())
|
||||
@@ -21,7 +23,7 @@ export const useCharacterStore = defineStore('characters', () => {
|
||||
|
||||
characters.value.clear()
|
||||
for (const char of data) {
|
||||
characters.value.set(char.id, char)
|
||||
characters.value.set(char.id, parse(CharacterWithRelationsSchema, char))
|
||||
}
|
||||
}, { immediate: true })
|
||||
}
|
||||
@@ -34,7 +36,8 @@ export const useCharacterStore = defineStore('characters', () => {
|
||||
if (!res.ok) {
|
||||
throw new Error('Failed to fetch character')
|
||||
}
|
||||
const character = await res.json()
|
||||
const data = await res.json()
|
||||
const character = parse(CharacterWithRelationsSchema, data)
|
||||
|
||||
characters.value.set(character.id, character)
|
||||
return character
|
||||
@@ -49,7 +52,8 @@ export const useCharacterStore = defineStore('characters', () => {
|
||||
if (!res.ok) {
|
||||
throw new Error('Failed to create character')
|
||||
}
|
||||
const character = await res.json()
|
||||
const data = await res.json()
|
||||
const character = parse(CharacterWithRelationsSchema, data)
|
||||
|
||||
characters.value.set(character.id, character)
|
||||
return character
|
||||
@@ -58,14 +62,16 @@ export const useCharacterStore = defineStore('characters', () => {
|
||||
|
||||
async function update(id: string, payload: UpdateCharacterPayload) {
|
||||
return useAsyncState(async () => {
|
||||
const res = await client.api.characters[':id'].$patch({
|
||||
const res = await (client.api.characters[':id'].$patch)({
|
||||
param: { id },
|
||||
// @ts-expect-error FIXME: hono client typing misses json option for this route
|
||||
json: payload,
|
||||
})
|
||||
if (!res.ok) {
|
||||
throw new Error('Failed to update character')
|
||||
}
|
||||
const character = await res.json()
|
||||
const data = await res.json()
|
||||
const character = parse(CharacterWithRelationsSchema, data)
|
||||
|
||||
characters.value.set(character.id, character)
|
||||
return character
|
||||
@@ -87,7 +93,7 @@ export const useCharacterStore = defineStore('characters', () => {
|
||||
|
||||
async function like(id: string) {
|
||||
return useAsyncState(async () => {
|
||||
const res = await client.api.characters[':id'].$patch({
|
||||
const res = await client.api.characters[':id'].like.$post({
|
||||
param: { id },
|
||||
})
|
||||
if (!res.ok) {
|
||||
@@ -100,7 +106,7 @@ export const useCharacterStore = defineStore('characters', () => {
|
||||
|
||||
async function bookmark(id: string) {
|
||||
return useAsyncState(async () => {
|
||||
const res = await client.api.characters[':id'].$patch({
|
||||
const res = await client.api.characters[':id'].bookmark.$post({
|
||||
param: { id },
|
||||
})
|
||||
if (!res.ok) {
|
||||
|
||||
@@ -77,6 +77,7 @@ export const CharacterBaseSchema = object({
|
||||
characterId: string(),
|
||||
createdAt: DateSchema,
|
||||
updatedAt: DateSchema,
|
||||
deletedAt: optional(DateSchema),
|
||||
})
|
||||
|
||||
export const CharacterCapabilitySchema = object({
|
||||
@@ -121,12 +122,12 @@ export const CharacterPromptSchema = object({
|
||||
|
||||
export const CharacterWithRelationsSchema = object({
|
||||
...CharacterBaseSchema.entries,
|
||||
capabilities: array(CharacterCapabilitySchema),
|
||||
avatarModels: array(AvatarModelSchema),
|
||||
i18n: array(CharacterI18nSchema),
|
||||
prompts: array(CharacterPromptSchema),
|
||||
likes: array(object({ userId: string(), characterId: string() })),
|
||||
bookmarks: array(object({ userId: string(), characterId: string() })),
|
||||
capabilities: optional(array(CharacterCapabilitySchema)),
|
||||
avatarModels: optional(array(AvatarModelSchema)),
|
||||
i18n: optional(array(CharacterI18nSchema)),
|
||||
prompts: optional(array(CharacterPromptSchema)),
|
||||
likes: optional(array(object({ userId: string(), characterId: string() }))),
|
||||
bookmarks: optional(array(object({ userId: string(), characterId: string() }))),
|
||||
})
|
||||
|
||||
// --- API Request Schemas ---
|
||||
|
||||
Reference in New Issue
Block a user