diff --git a/prisma/migrations/20260214055716_add_expressions/migration.sql b/prisma/migrations/20260214055716_add_expressions/migration.sql new file mode 100644 index 0000000..7b318bd --- /dev/null +++ b/prisma/migrations/20260214055716_add_expressions/migration.sql @@ -0,0 +1,12 @@ +-- AlterTable +ALTER TABLE "generations" ADD COLUMN "expression" TEXT; + +-- CreateTable +CREATE TABLE "expressions" ( + "id" TEXT NOT NULL PRIMARY KEY, + "name" TEXT NOT NULL, + "image_id" TEXT NOT NULL, + "created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" DATETIME NOT NULL, + CONSTRAINT "expressions_image_id_fkey" FOREIGN KEY ("image_id") REFERENCES "assets" ("id") ON DELETE RESTRICT ON UPDATE CASCADE +); diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 1dd8544..a8a2324 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -25,6 +25,7 @@ model Asset { equipments Equipment[] generations Generation[] poses Pose[] + expressions Expression[] @@map("assets") } @@ -69,6 +70,7 @@ model Generation { imageId String @map("image_id") userPrompt String? @map("user_prompt") pose String? + expression String? createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") @@ -137,3 +139,16 @@ model Pose { @@map("poses") } + +model Expression { + id String @id + name String + imageId String @map("image_id") + createdAt DateTime @default(now()) @map("created_at") + updatedAt DateTime @updatedAt @map("updated_at") + + // Relations + image Asset @relation(fields: [imageId], references: [id]) + + @@map("expressions") +} diff --git a/public/expressions/character_pose_1.webp b/public/expressions/expression_1.webp similarity index 100% rename from public/expressions/character_pose_1.webp rename to public/expressions/expression_1.webp diff --git a/public/expressions/character_pose_2.webp b/public/expressions/expression_2.webp similarity index 100% rename from public/expressions/character_pose_2.webp rename to public/expressions/expression_2.webp diff --git a/public/expressions/character_pose_3.webp b/public/expressions/expression_3.webp similarity index 100% rename from public/expressions/character_pose_3.webp rename to public/expressions/expression_3.webp diff --git a/public/expressions/character_pose_4.webp b/public/expressions/expression_4.webp similarity index 100% rename from public/expressions/character_pose_4.webp rename to public/expressions/expression_4.webp diff --git a/public/expressions/character_pose_5.webp b/public/expressions/expression_5.webp similarity index 100% rename from public/expressions/character_pose_5.webp rename to public/expressions/expression_5.webp diff --git a/public/expressions/character_pose_6.webp b/public/expressions/expression_6.webp similarity index 100% rename from public/expressions/character_pose_6.webp rename to public/expressions/expression_6.webp diff --git a/public/expressions/character_pose_7.webp b/public/expressions/expression_7.webp similarity index 100% rename from public/expressions/character_pose_7.webp rename to public/expressions/expression_7.webp diff --git a/public/expressions/character_pose_8.webp b/public/expressions/expression_8.webp similarity index 100% rename from public/expressions/character_pose_8.webp rename to public/expressions/expression_8.webp diff --git a/public/expressions/character_pose_9.webp b/public/expressions/expression_9.webp similarity index 100% rename from public/expressions/character_pose_9.webp rename to public/expressions/expression_9.webp diff --git a/src/api/expression.ts b/src/api/expression.ts new file mode 100644 index 0000000..97bc961 --- /dev/null +++ b/src/api/expression.ts @@ -0,0 +1,39 @@ +import { zValidator } from '@hono/zod-validator' +import { Hono } from 'hono' +import { z } from 'zod' +import { expressionService } from '../service/expression' + +const app = new Hono() + +// Zod schema for validation +const createSchema = z.object({ + name: z.string().min(1), + image: z.instanceof(File), +}) + +const route = app + .get('/', async (c) => { + const expressions = await expressionService.listExpressions() + return c.json(expressions) + }) + .post('/', zValidator('form', createSchema), async (c) => { + const { name, image } = c.req.valid('form') + try { + const expression = await expressionService.createExpression(name, image) + return c.json(expression, 201) + } catch (e) { + console.error('Failed to create expression', e) + return c.json({ error: e instanceof Error ? e.message : 'Unknown error' }, 500) + } + }) + .delete('/:id', async (c) => { + const id = c.req.param('id') + try { + await expressionService.deleteExpression(id) + return c.json({ success: true }) + } catch (e) { + return c.json({ error: e instanceof Error ? e.message : 'Unknown error' }, 500) + } + }) + +export default route diff --git a/src/api/generation.test.ts b/src/api/generation.test.ts index 0fb2894..0515249 100644 --- a/src/api/generation.test.ts +++ b/src/api/generation.test.ts @@ -47,6 +47,7 @@ describe('Generation API', () => { ['eq1', 'eq2'], undefined, undefined, + undefined, ) }) @@ -71,6 +72,7 @@ describe('Generation API', () => { ['eq1', 'eq2'], 'test prompt', undefined, + undefined, ) }) }) diff --git a/src/api/generation.ts b/src/api/generation.ts index 746dd86..58c7581 100644 --- a/src/api/generation.ts +++ b/src/api/generation.ts @@ -17,6 +17,7 @@ const createSchema = z.object({ equipmentIds: z.array(z.string()), userPrompt: z.string().optional(), poseId: z.string().optional(), + expressionId: z.string().optional(), }) const route = app @@ -30,13 +31,14 @@ const route = app return c.json(result) }) .post('/', zValidator('json', createSchema), async (c) => { - const { characterId, equipmentIds, userPrompt, poseId } = c.req.valid('json') + const { characterId, equipmentIds, userPrompt, poseId, expressionId } = c.req.valid('json') try { const result = await generationService.createGeneration( characterId, equipmentIds, userPrompt, poseId, + expressionId, ) return c.json(result, 201) } catch (e) { diff --git a/src/generated/prisma/browser.ts b/src/generated/prisma/browser.ts index 781c7d8..5b0fc85 100644 --- a/src/generated/prisma/browser.ts +++ b/src/generated/prisma/browser.ts @@ -62,3 +62,8 @@ export type Setting = Prisma.SettingModel * */ export type Pose = Prisma.PoseModel +/** + * Model Expression + * + */ +export type Expression = Prisma.ExpressionModel diff --git a/src/generated/prisma/client.ts b/src/generated/prisma/client.ts index e433d1d..34ba36c 100644 --- a/src/generated/prisma/client.ts +++ b/src/generated/prisma/client.ts @@ -84,3 +84,8 @@ export type Setting = Prisma.SettingModel * */ export type Pose = Prisma.PoseModel +/** + * Model Expression + * + */ +export type Expression = Prisma.ExpressionModel diff --git a/src/generated/prisma/internal/class.ts b/src/generated/prisma/internal/class.ts index 0a84dd8..3ef27b7 100644 --- a/src/generated/prisma/internal/class.ts +++ b/src/generated/prisma/internal/class.ts @@ -20,7 +20,7 @@ const config: runtime.GetPrismaClientConfig = { "clientVersion": "7.3.0", "engineVersion": "9d6ad21cbbceab97458517b147a6a09ff43aa735", "activeProvider": "sqlite", - "inlineSchema": "// This is your Prisma schema file,\n// learn more about it in the docs: https://pris.ly/d/prisma-schema\n\ngenerator client {\n provider = \"prisma-client\"\n output = \"../src/generated/prisma\"\n engineType = \"client\"\n runtime = \"bun\"\n}\n\ndatasource db {\n provider = \"sqlite\"\n}\n\nmodel Asset {\n id String @id\n name String\n type String\n path String\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n\n // Relations\n characters Character[]\n equipments Equipment[]\n generations Generation[]\n poses Pose[]\n\n @@map(\"assets\")\n}\n\nmodel Character {\n id String @id\n name String\n description String?\n imageId String @map(\"image_id\")\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n\n // Relations\n image Asset @relation(fields: [imageId], references: [id])\n generations Generation[]\n\n @@map(\"characters\")\n}\n\nmodel Equipment {\n id String @id\n name String\n description String\n category String\n subCategory String? @map(\"sub_category\")\n imageId String @map(\"image_id\")\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n\n // Relations\n image Asset @relation(fields: [imageId], references: [id])\n generations GenerationEquipment[]\n outfits OutfitEquipment[]\n\n @@index([category, subCategory])\n @@map(\"equipments\")\n}\n\nmodel Generation {\n id String @id\n characterId String @map(\"character_id\")\n imageId String @map(\"image_id\")\n userPrompt String? @map(\"user_prompt\")\n pose String?\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n\n // Relations\n character Character @relation(fields: [characterId], references: [id])\n image Asset @relation(fields: [imageId], references: [id])\n equipments GenerationEquipment[]\n\n @@map(\"generations\")\n}\n\nmodel GenerationEquipment {\n generationId String @map(\"generation_id\")\n equipmentId String @map(\"equipment_id\")\n\n generation Generation @relation(fields: [generationId], references: [id])\n equipment Equipment @relation(fields: [equipmentId], references: [id])\n\n @@id([generationId, equipmentId])\n @@map(\"generation_equipments\")\n}\n\nmodel Outfit {\n id String @id\n name String\n prompt String?\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n\n // Relations\n equipments OutfitEquipment[]\n\n @@map(\"outfits\")\n}\n\nmodel OutfitEquipment {\n outfitId String @map(\"outfit_id\")\n equipmentId String @map(\"equipment_id\")\n\n outfit Outfit @relation(fields: [outfitId], references: [id], onDelete: Cascade)\n equipment Equipment @relation(fields: [equipmentId], references: [id], onDelete: Cascade)\n\n @@id([outfitId, equipmentId])\n @@map(\"outfit_equipments\")\n}\n\nmodel Setting {\n key String @id\n value String\n\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n\n @@map(\"settings\")\n}\n\nmodel Pose {\n id String @id\n name String\n imageId String @map(\"image_id\")\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n\n // Relations\n image Asset @relation(fields: [imageId], references: [id])\n\n @@map(\"poses\")\n}\n", + "inlineSchema": "// This is your Prisma schema file,\n// learn more about it in the docs: https://pris.ly/d/prisma-schema\n\ngenerator client {\n provider = \"prisma-client\"\n output = \"../src/generated/prisma\"\n engineType = \"client\"\n runtime = \"bun\"\n}\n\ndatasource db {\n provider = \"sqlite\"\n}\n\nmodel Asset {\n id String @id\n name String\n type String\n path String\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n\n // Relations\n characters Character[]\n equipments Equipment[]\n generations Generation[]\n poses Pose[]\n expressions Expression[]\n\n @@map(\"assets\")\n}\n\nmodel Character {\n id String @id\n name String\n description String?\n imageId String @map(\"image_id\")\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n\n // Relations\n image Asset @relation(fields: [imageId], references: [id])\n generations Generation[]\n\n @@map(\"characters\")\n}\n\nmodel Equipment {\n id String @id\n name String\n description String\n category String\n subCategory String? @map(\"sub_category\")\n imageId String @map(\"image_id\")\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n\n // Relations\n image Asset @relation(fields: [imageId], references: [id])\n generations GenerationEquipment[]\n outfits OutfitEquipment[]\n\n @@index([category, subCategory])\n @@map(\"equipments\")\n}\n\nmodel Generation {\n id String @id\n characterId String @map(\"character_id\")\n imageId String @map(\"image_id\")\n userPrompt String? @map(\"user_prompt\")\n pose String?\n expression String?\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n\n // Relations\n character Character @relation(fields: [characterId], references: [id])\n image Asset @relation(fields: [imageId], references: [id])\n equipments GenerationEquipment[]\n\n @@map(\"generations\")\n}\n\nmodel GenerationEquipment {\n generationId String @map(\"generation_id\")\n equipmentId String @map(\"equipment_id\")\n\n generation Generation @relation(fields: [generationId], references: [id])\n equipment Equipment @relation(fields: [equipmentId], references: [id])\n\n @@id([generationId, equipmentId])\n @@map(\"generation_equipments\")\n}\n\nmodel Outfit {\n id String @id\n name String\n prompt String?\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n\n // Relations\n equipments OutfitEquipment[]\n\n @@map(\"outfits\")\n}\n\nmodel OutfitEquipment {\n outfitId String @map(\"outfit_id\")\n equipmentId String @map(\"equipment_id\")\n\n outfit Outfit @relation(fields: [outfitId], references: [id], onDelete: Cascade)\n equipment Equipment @relation(fields: [equipmentId], references: [id], onDelete: Cascade)\n\n @@id([outfitId, equipmentId])\n @@map(\"outfit_equipments\")\n}\n\nmodel Setting {\n key String @id\n value String\n\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n\n @@map(\"settings\")\n}\n\nmodel Pose {\n id String @id\n name String\n imageId String @map(\"image_id\")\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n\n // Relations\n image Asset @relation(fields: [imageId], references: [id])\n\n @@map(\"poses\")\n}\n\nmodel Expression {\n id String @id\n name String\n imageId String @map(\"image_id\")\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n\n // Relations\n image Asset @relation(fields: [imageId], references: [id])\n\n @@map(\"expressions\")\n}\n", "runtimeDataModel": { "models": {}, "enums": {}, @@ -28,7 +28,7 @@ const config: runtime.GetPrismaClientConfig = { } } -config.runtimeDataModel = JSON.parse("{\"models\":{\"Asset\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"type\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"path\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"updated_at\"},{\"name\":\"characters\",\"kind\":\"object\",\"type\":\"Character\",\"relationName\":\"AssetToCharacter\"},{\"name\":\"equipments\",\"kind\":\"object\",\"type\":\"Equipment\",\"relationName\":\"AssetToEquipment\"},{\"name\":\"generations\",\"kind\":\"object\",\"type\":\"Generation\",\"relationName\":\"AssetToGeneration\"},{\"name\":\"poses\",\"kind\":\"object\",\"type\":\"Pose\",\"relationName\":\"AssetToPose\"}],\"dbName\":\"assets\"},\"Character\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"description\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"imageId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"image_id\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"updated_at\"},{\"name\":\"image\",\"kind\":\"object\",\"type\":\"Asset\",\"relationName\":\"AssetToCharacter\"},{\"name\":\"generations\",\"kind\":\"object\",\"type\":\"Generation\",\"relationName\":\"CharacterToGeneration\"}],\"dbName\":\"characters\"},\"Equipment\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"description\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"category\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"subCategory\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"sub_category\"},{\"name\":\"imageId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"image_id\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"updated_at\"},{\"name\":\"image\",\"kind\":\"object\",\"type\":\"Asset\",\"relationName\":\"AssetToEquipment\"},{\"name\":\"generations\",\"kind\":\"object\",\"type\":\"GenerationEquipment\",\"relationName\":\"EquipmentToGenerationEquipment\"},{\"name\":\"outfits\",\"kind\":\"object\",\"type\":\"OutfitEquipment\",\"relationName\":\"EquipmentToOutfitEquipment\"}],\"dbName\":\"equipments\"},\"Generation\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"characterId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"character_id\"},{\"name\":\"imageId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"image_id\"},{\"name\":\"userPrompt\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"user_prompt\"},{\"name\":\"pose\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"updated_at\"},{\"name\":\"character\",\"kind\":\"object\",\"type\":\"Character\",\"relationName\":\"CharacterToGeneration\"},{\"name\":\"image\",\"kind\":\"object\",\"type\":\"Asset\",\"relationName\":\"AssetToGeneration\"},{\"name\":\"equipments\",\"kind\":\"object\",\"type\":\"GenerationEquipment\",\"relationName\":\"GenerationToGenerationEquipment\"}],\"dbName\":\"generations\"},\"GenerationEquipment\":{\"fields\":[{\"name\":\"generationId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"generation_id\"},{\"name\":\"equipmentId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"equipment_id\"},{\"name\":\"generation\",\"kind\":\"object\",\"type\":\"Generation\",\"relationName\":\"GenerationToGenerationEquipment\"},{\"name\":\"equipment\",\"kind\":\"object\",\"type\":\"Equipment\",\"relationName\":\"EquipmentToGenerationEquipment\"}],\"dbName\":\"generation_equipments\"},\"Outfit\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"prompt\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"updated_at\"},{\"name\":\"equipments\",\"kind\":\"object\",\"type\":\"OutfitEquipment\",\"relationName\":\"OutfitToOutfitEquipment\"}],\"dbName\":\"outfits\"},\"OutfitEquipment\":{\"fields\":[{\"name\":\"outfitId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"outfit_id\"},{\"name\":\"equipmentId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"equipment_id\"},{\"name\":\"outfit\",\"kind\":\"object\",\"type\":\"Outfit\",\"relationName\":\"OutfitToOutfitEquipment\"},{\"name\":\"equipment\",\"kind\":\"object\",\"type\":\"Equipment\",\"relationName\":\"EquipmentToOutfitEquipment\"}],\"dbName\":\"outfit_equipments\"},\"Setting\":{\"fields\":[{\"name\":\"key\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"value\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"updated_at\"}],\"dbName\":\"settings\"},\"Pose\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"imageId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"image_id\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"updated_at\"},{\"name\":\"image\",\"kind\":\"object\",\"type\":\"Asset\",\"relationName\":\"AssetToPose\"}],\"dbName\":\"poses\"}},\"enums\":{},\"types\":{}}") +config.runtimeDataModel = JSON.parse("{\"models\":{\"Asset\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"type\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"path\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"updated_at\"},{\"name\":\"characters\",\"kind\":\"object\",\"type\":\"Character\",\"relationName\":\"AssetToCharacter\"},{\"name\":\"equipments\",\"kind\":\"object\",\"type\":\"Equipment\",\"relationName\":\"AssetToEquipment\"},{\"name\":\"generations\",\"kind\":\"object\",\"type\":\"Generation\",\"relationName\":\"AssetToGeneration\"},{\"name\":\"poses\",\"kind\":\"object\",\"type\":\"Pose\",\"relationName\":\"AssetToPose\"},{\"name\":\"expressions\",\"kind\":\"object\",\"type\":\"Expression\",\"relationName\":\"AssetToExpression\"}],\"dbName\":\"assets\"},\"Character\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"description\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"imageId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"image_id\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"updated_at\"},{\"name\":\"image\",\"kind\":\"object\",\"type\":\"Asset\",\"relationName\":\"AssetToCharacter\"},{\"name\":\"generations\",\"kind\":\"object\",\"type\":\"Generation\",\"relationName\":\"CharacterToGeneration\"}],\"dbName\":\"characters\"},\"Equipment\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"description\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"category\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"subCategory\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"sub_category\"},{\"name\":\"imageId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"image_id\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"updated_at\"},{\"name\":\"image\",\"kind\":\"object\",\"type\":\"Asset\",\"relationName\":\"AssetToEquipment\"},{\"name\":\"generations\",\"kind\":\"object\",\"type\":\"GenerationEquipment\",\"relationName\":\"EquipmentToGenerationEquipment\"},{\"name\":\"outfits\",\"kind\":\"object\",\"type\":\"OutfitEquipment\",\"relationName\":\"EquipmentToOutfitEquipment\"}],\"dbName\":\"equipments\"},\"Generation\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"characterId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"character_id\"},{\"name\":\"imageId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"image_id\"},{\"name\":\"userPrompt\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"user_prompt\"},{\"name\":\"pose\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"expression\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"updated_at\"},{\"name\":\"character\",\"kind\":\"object\",\"type\":\"Character\",\"relationName\":\"CharacterToGeneration\"},{\"name\":\"image\",\"kind\":\"object\",\"type\":\"Asset\",\"relationName\":\"AssetToGeneration\"},{\"name\":\"equipments\",\"kind\":\"object\",\"type\":\"GenerationEquipment\",\"relationName\":\"GenerationToGenerationEquipment\"}],\"dbName\":\"generations\"},\"GenerationEquipment\":{\"fields\":[{\"name\":\"generationId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"generation_id\"},{\"name\":\"equipmentId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"equipment_id\"},{\"name\":\"generation\",\"kind\":\"object\",\"type\":\"Generation\",\"relationName\":\"GenerationToGenerationEquipment\"},{\"name\":\"equipment\",\"kind\":\"object\",\"type\":\"Equipment\",\"relationName\":\"EquipmentToGenerationEquipment\"}],\"dbName\":\"generation_equipments\"},\"Outfit\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"prompt\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"updated_at\"},{\"name\":\"equipments\",\"kind\":\"object\",\"type\":\"OutfitEquipment\",\"relationName\":\"OutfitToOutfitEquipment\"}],\"dbName\":\"outfits\"},\"OutfitEquipment\":{\"fields\":[{\"name\":\"outfitId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"outfit_id\"},{\"name\":\"equipmentId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"equipment_id\"},{\"name\":\"outfit\",\"kind\":\"object\",\"type\":\"Outfit\",\"relationName\":\"OutfitToOutfitEquipment\"},{\"name\":\"equipment\",\"kind\":\"object\",\"type\":\"Equipment\",\"relationName\":\"EquipmentToOutfitEquipment\"}],\"dbName\":\"outfit_equipments\"},\"Setting\":{\"fields\":[{\"name\":\"key\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"value\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"updated_at\"}],\"dbName\":\"settings\"},\"Pose\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"imageId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"image_id\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"updated_at\"},{\"name\":\"image\",\"kind\":\"object\",\"type\":\"Asset\",\"relationName\":\"AssetToPose\"}],\"dbName\":\"poses\"},\"Expression\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"imageId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"image_id\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"updated_at\"},{\"name\":\"image\",\"kind\":\"object\",\"type\":\"Asset\",\"relationName\":\"AssetToExpression\"}],\"dbName\":\"expressions\"}},\"enums\":{},\"types\":{}}") async function decodeBase64AsWasm(wasmBase64: string): Promise { const { Buffer } = await import('node:buffer') @@ -265,6 +265,16 @@ export interface PrismaClient< * ``` */ get pose(): Prisma.PoseDelegate; + + /** + * `prisma.expression`: Exposes CRUD operations for the **Expression** model. + * Example usage: + * ```ts + * // Fetch zero or more Expressions + * const expressions = await prisma.expression.findMany() + * ``` + */ + get expression(): Prisma.ExpressionDelegate; } export function getPrismaClientClass(): PrismaClientConstructor { diff --git a/src/generated/prisma/internal/prismaNamespace.ts b/src/generated/prisma/internal/prismaNamespace.ts index e29c78a..f93c359 100644 --- a/src/generated/prisma/internal/prismaNamespace.ts +++ b/src/generated/prisma/internal/prismaNamespace.ts @@ -392,7 +392,8 @@ export const ModelName = { Outfit: 'Outfit', OutfitEquipment: 'OutfitEquipment', Setting: 'Setting', - Pose: 'Pose' + Pose: 'Pose', + Expression: 'Expression' } as const export type ModelName = (typeof ModelName)[keyof typeof ModelName] @@ -408,7 +409,7 @@ export type TypeMap + fields: Prisma.ExpressionFieldRefs + operations: { + findUnique: { + args: Prisma.ExpressionFindUniqueArgs + result: runtime.Types.Utils.PayloadToResult | null + } + findUniqueOrThrow: { + args: Prisma.ExpressionFindUniqueOrThrowArgs + result: runtime.Types.Utils.PayloadToResult + } + findFirst: { + args: Prisma.ExpressionFindFirstArgs + result: runtime.Types.Utils.PayloadToResult | null + } + findFirstOrThrow: { + args: Prisma.ExpressionFindFirstOrThrowArgs + result: runtime.Types.Utils.PayloadToResult + } + findMany: { + args: Prisma.ExpressionFindManyArgs + result: runtime.Types.Utils.PayloadToResult[] + } + create: { + args: Prisma.ExpressionCreateArgs + result: runtime.Types.Utils.PayloadToResult + } + createMany: { + args: Prisma.ExpressionCreateManyArgs + result: BatchPayload + } + createManyAndReturn: { + args: Prisma.ExpressionCreateManyAndReturnArgs + result: runtime.Types.Utils.PayloadToResult[] + } + delete: { + args: Prisma.ExpressionDeleteArgs + result: runtime.Types.Utils.PayloadToResult + } + update: { + args: Prisma.ExpressionUpdateArgs + result: runtime.Types.Utils.PayloadToResult + } + deleteMany: { + args: Prisma.ExpressionDeleteManyArgs + result: BatchPayload + } + updateMany: { + args: Prisma.ExpressionUpdateManyArgs + result: BatchPayload + } + updateManyAndReturn: { + args: Prisma.ExpressionUpdateManyAndReturnArgs + result: runtime.Types.Utils.PayloadToResult[] + } + upsert: { + args: Prisma.ExpressionUpsertArgs + result: runtime.Types.Utils.PayloadToResult + } + aggregate: { + args: Prisma.ExpressionAggregateArgs + result: runtime.Types.Utils.Optional + } + groupBy: { + args: Prisma.ExpressionGroupByArgs + result: runtime.Types.Utils.Optional[] + } + count: { + args: Prisma.ExpressionCountArgs + result: runtime.Types.Utils.Optional | number + } + } + } } } & { other: { @@ -1158,6 +1233,7 @@ export const GenerationScalarFieldEnum = { imageId: 'imageId', userPrompt: 'userPrompt', pose: 'pose', + expression: 'expression', createdAt: 'createdAt', updatedAt: 'updatedAt' } as const @@ -1213,6 +1289,17 @@ export const PoseScalarFieldEnum = { export type PoseScalarFieldEnum = (typeof PoseScalarFieldEnum)[keyof typeof PoseScalarFieldEnum] +export const ExpressionScalarFieldEnum = { + id: 'id', + name: 'name', + imageId: 'imageId', + createdAt: 'createdAt', + updatedAt: 'updatedAt' +} as const + +export type ExpressionScalarFieldEnum = (typeof ExpressionScalarFieldEnum)[keyof typeof ExpressionScalarFieldEnum] + + export const SortOrder = { asc: 'asc', desc: 'desc' @@ -1359,6 +1446,7 @@ export type GlobalOmitConfig = { outfitEquipment?: Prisma.OutfitEquipmentOmit setting?: Prisma.SettingOmit pose?: Prisma.PoseOmit + expression?: Prisma.ExpressionOmit } /* Types for Logging */ diff --git a/src/generated/prisma/internal/prismaNamespaceBrowser.ts b/src/generated/prisma/internal/prismaNamespaceBrowser.ts index f6a3951..ecbca1d 100644 --- a/src/generated/prisma/internal/prismaNamespaceBrowser.ts +++ b/src/generated/prisma/internal/prismaNamespaceBrowser.ts @@ -59,7 +59,8 @@ export const ModelName = { Outfit: 'Outfit', OutfitEquipment: 'OutfitEquipment', Setting: 'Setting', - Pose: 'Pose' + Pose: 'Pose', + Expression: 'Expression' } as const export type ModelName = (typeof ModelName)[keyof typeof ModelName] @@ -119,6 +120,7 @@ export const GenerationScalarFieldEnum = { imageId: 'imageId', userPrompt: 'userPrompt', pose: 'pose', + expression: 'expression', createdAt: 'createdAt', updatedAt: 'updatedAt' } as const @@ -174,6 +176,17 @@ export const PoseScalarFieldEnum = { export type PoseScalarFieldEnum = (typeof PoseScalarFieldEnum)[keyof typeof PoseScalarFieldEnum] +export const ExpressionScalarFieldEnum = { + id: 'id', + name: 'name', + imageId: 'imageId', + createdAt: 'createdAt', + updatedAt: 'updatedAt' +} as const + +export type ExpressionScalarFieldEnum = (typeof ExpressionScalarFieldEnum)[keyof typeof ExpressionScalarFieldEnum] + + export const SortOrder = { asc: 'asc', desc: 'desc' diff --git a/src/generated/prisma/models.ts b/src/generated/prisma/models.ts index 3e35619..37eefd9 100644 --- a/src/generated/prisma/models.ts +++ b/src/generated/prisma/models.ts @@ -17,4 +17,5 @@ export type * from './models/Outfit.ts' export type * from './models/OutfitEquipment.ts' export type * from './models/Setting.ts' export type * from './models/Pose.ts' +export type * from './models/Expression.ts' export type * from './commonInputTypes.ts' \ No newline at end of file diff --git a/src/generated/prisma/models/Asset.ts b/src/generated/prisma/models/Asset.ts index dc4726d..ac903a4 100644 --- a/src/generated/prisma/models/Asset.ts +++ b/src/generated/prisma/models/Asset.ts @@ -194,6 +194,7 @@ export type AssetWhereInput = { equipments?: Prisma.EquipmentListRelationFilter generations?: Prisma.GenerationListRelationFilter poses?: Prisma.PoseListRelationFilter + expressions?: Prisma.ExpressionListRelationFilter } export type AssetOrderByWithRelationInput = { @@ -207,6 +208,7 @@ export type AssetOrderByWithRelationInput = { equipments?: Prisma.EquipmentOrderByRelationAggregateInput generations?: Prisma.GenerationOrderByRelationAggregateInput poses?: Prisma.PoseOrderByRelationAggregateInput + expressions?: Prisma.ExpressionOrderByRelationAggregateInput } export type AssetWhereUniqueInput = Prisma.AtLeast<{ @@ -223,6 +225,7 @@ export type AssetWhereUniqueInput = Prisma.AtLeast<{ equipments?: Prisma.EquipmentListRelationFilter generations?: Prisma.GenerationListRelationFilter poses?: Prisma.PoseListRelationFilter + expressions?: Prisma.ExpressionListRelationFilter }, "id"> export type AssetOrderByWithAggregationInput = { @@ -260,6 +263,7 @@ export type AssetCreateInput = { equipments?: Prisma.EquipmentCreateNestedManyWithoutImageInput generations?: Prisma.GenerationCreateNestedManyWithoutImageInput poses?: Prisma.PoseCreateNestedManyWithoutImageInput + expressions?: Prisma.ExpressionCreateNestedManyWithoutImageInput } export type AssetUncheckedCreateInput = { @@ -273,6 +277,7 @@ export type AssetUncheckedCreateInput = { equipments?: Prisma.EquipmentUncheckedCreateNestedManyWithoutImageInput generations?: Prisma.GenerationUncheckedCreateNestedManyWithoutImageInput poses?: Prisma.PoseUncheckedCreateNestedManyWithoutImageInput + expressions?: Prisma.ExpressionUncheckedCreateNestedManyWithoutImageInput } export type AssetUpdateInput = { @@ -286,6 +291,7 @@ export type AssetUpdateInput = { equipments?: Prisma.EquipmentUpdateManyWithoutImageNestedInput generations?: Prisma.GenerationUpdateManyWithoutImageNestedInput poses?: Prisma.PoseUpdateManyWithoutImageNestedInput + expressions?: Prisma.ExpressionUpdateManyWithoutImageNestedInput } export type AssetUncheckedUpdateInput = { @@ -299,6 +305,7 @@ export type AssetUncheckedUpdateInput = { equipments?: Prisma.EquipmentUncheckedUpdateManyWithoutImageNestedInput generations?: Prisma.GenerationUncheckedUpdateManyWithoutImageNestedInput poses?: Prisma.PoseUncheckedUpdateManyWithoutImageNestedInput + expressions?: Prisma.ExpressionUncheckedUpdateManyWithoutImageNestedInput } export type AssetCreateManyInput = { @@ -424,6 +431,20 @@ export type AssetUpdateOneRequiredWithoutPosesNestedInput = { update?: Prisma.XOR, Prisma.AssetUncheckedUpdateWithoutPosesInput> } +export type AssetCreateNestedOneWithoutExpressionsInput = { + create?: Prisma.XOR + connectOrCreate?: Prisma.AssetCreateOrConnectWithoutExpressionsInput + connect?: Prisma.AssetWhereUniqueInput +} + +export type AssetUpdateOneRequiredWithoutExpressionsNestedInput = { + create?: Prisma.XOR + connectOrCreate?: Prisma.AssetCreateOrConnectWithoutExpressionsInput + upsert?: Prisma.AssetUpsertWithoutExpressionsInput + connect?: Prisma.AssetWhereUniqueInput + update?: Prisma.XOR, Prisma.AssetUncheckedUpdateWithoutExpressionsInput> +} + export type AssetCreateWithoutCharactersInput = { id: string name: string @@ -434,6 +455,7 @@ export type AssetCreateWithoutCharactersInput = { equipments?: Prisma.EquipmentCreateNestedManyWithoutImageInput generations?: Prisma.GenerationCreateNestedManyWithoutImageInput poses?: Prisma.PoseCreateNestedManyWithoutImageInput + expressions?: Prisma.ExpressionCreateNestedManyWithoutImageInput } export type AssetUncheckedCreateWithoutCharactersInput = { @@ -446,6 +468,7 @@ export type AssetUncheckedCreateWithoutCharactersInput = { equipments?: Prisma.EquipmentUncheckedCreateNestedManyWithoutImageInput generations?: Prisma.GenerationUncheckedCreateNestedManyWithoutImageInput poses?: Prisma.PoseUncheckedCreateNestedManyWithoutImageInput + expressions?: Prisma.ExpressionUncheckedCreateNestedManyWithoutImageInput } export type AssetCreateOrConnectWithoutCharactersInput = { @@ -474,6 +497,7 @@ export type AssetUpdateWithoutCharactersInput = { equipments?: Prisma.EquipmentUpdateManyWithoutImageNestedInput generations?: Prisma.GenerationUpdateManyWithoutImageNestedInput poses?: Prisma.PoseUpdateManyWithoutImageNestedInput + expressions?: Prisma.ExpressionUpdateManyWithoutImageNestedInput } export type AssetUncheckedUpdateWithoutCharactersInput = { @@ -486,6 +510,7 @@ export type AssetUncheckedUpdateWithoutCharactersInput = { equipments?: Prisma.EquipmentUncheckedUpdateManyWithoutImageNestedInput generations?: Prisma.GenerationUncheckedUpdateManyWithoutImageNestedInput poses?: Prisma.PoseUncheckedUpdateManyWithoutImageNestedInput + expressions?: Prisma.ExpressionUncheckedUpdateManyWithoutImageNestedInput } export type AssetCreateWithoutEquipmentsInput = { @@ -498,6 +523,7 @@ export type AssetCreateWithoutEquipmentsInput = { characters?: Prisma.CharacterCreateNestedManyWithoutImageInput generations?: Prisma.GenerationCreateNestedManyWithoutImageInput poses?: Prisma.PoseCreateNestedManyWithoutImageInput + expressions?: Prisma.ExpressionCreateNestedManyWithoutImageInput } export type AssetUncheckedCreateWithoutEquipmentsInput = { @@ -510,6 +536,7 @@ export type AssetUncheckedCreateWithoutEquipmentsInput = { characters?: Prisma.CharacterUncheckedCreateNestedManyWithoutImageInput generations?: Prisma.GenerationUncheckedCreateNestedManyWithoutImageInput poses?: Prisma.PoseUncheckedCreateNestedManyWithoutImageInput + expressions?: Prisma.ExpressionUncheckedCreateNestedManyWithoutImageInput } export type AssetCreateOrConnectWithoutEquipmentsInput = { @@ -538,6 +565,7 @@ export type AssetUpdateWithoutEquipmentsInput = { characters?: Prisma.CharacterUpdateManyWithoutImageNestedInput generations?: Prisma.GenerationUpdateManyWithoutImageNestedInput poses?: Prisma.PoseUpdateManyWithoutImageNestedInput + expressions?: Prisma.ExpressionUpdateManyWithoutImageNestedInput } export type AssetUncheckedUpdateWithoutEquipmentsInput = { @@ -550,6 +578,7 @@ export type AssetUncheckedUpdateWithoutEquipmentsInput = { characters?: Prisma.CharacterUncheckedUpdateManyWithoutImageNestedInput generations?: Prisma.GenerationUncheckedUpdateManyWithoutImageNestedInput poses?: Prisma.PoseUncheckedUpdateManyWithoutImageNestedInput + expressions?: Prisma.ExpressionUncheckedUpdateManyWithoutImageNestedInput } export type AssetCreateWithoutGenerationsInput = { @@ -562,6 +591,7 @@ export type AssetCreateWithoutGenerationsInput = { characters?: Prisma.CharacterCreateNestedManyWithoutImageInput equipments?: Prisma.EquipmentCreateNestedManyWithoutImageInput poses?: Prisma.PoseCreateNestedManyWithoutImageInput + expressions?: Prisma.ExpressionCreateNestedManyWithoutImageInput } export type AssetUncheckedCreateWithoutGenerationsInput = { @@ -574,6 +604,7 @@ export type AssetUncheckedCreateWithoutGenerationsInput = { characters?: Prisma.CharacterUncheckedCreateNestedManyWithoutImageInput equipments?: Prisma.EquipmentUncheckedCreateNestedManyWithoutImageInput poses?: Prisma.PoseUncheckedCreateNestedManyWithoutImageInput + expressions?: Prisma.ExpressionUncheckedCreateNestedManyWithoutImageInput } export type AssetCreateOrConnectWithoutGenerationsInput = { @@ -602,6 +633,7 @@ export type AssetUpdateWithoutGenerationsInput = { characters?: Prisma.CharacterUpdateManyWithoutImageNestedInput equipments?: Prisma.EquipmentUpdateManyWithoutImageNestedInput poses?: Prisma.PoseUpdateManyWithoutImageNestedInput + expressions?: Prisma.ExpressionUpdateManyWithoutImageNestedInput } export type AssetUncheckedUpdateWithoutGenerationsInput = { @@ -614,6 +646,7 @@ export type AssetUncheckedUpdateWithoutGenerationsInput = { characters?: Prisma.CharacterUncheckedUpdateManyWithoutImageNestedInput equipments?: Prisma.EquipmentUncheckedUpdateManyWithoutImageNestedInput poses?: Prisma.PoseUncheckedUpdateManyWithoutImageNestedInput + expressions?: Prisma.ExpressionUncheckedUpdateManyWithoutImageNestedInput } export type AssetCreateWithoutPosesInput = { @@ -626,6 +659,7 @@ export type AssetCreateWithoutPosesInput = { characters?: Prisma.CharacterCreateNestedManyWithoutImageInput equipments?: Prisma.EquipmentCreateNestedManyWithoutImageInput generations?: Prisma.GenerationCreateNestedManyWithoutImageInput + expressions?: Prisma.ExpressionCreateNestedManyWithoutImageInput } export type AssetUncheckedCreateWithoutPosesInput = { @@ -638,6 +672,7 @@ export type AssetUncheckedCreateWithoutPosesInput = { characters?: Prisma.CharacterUncheckedCreateNestedManyWithoutImageInput equipments?: Prisma.EquipmentUncheckedCreateNestedManyWithoutImageInput generations?: Prisma.GenerationUncheckedCreateNestedManyWithoutImageInput + expressions?: Prisma.ExpressionUncheckedCreateNestedManyWithoutImageInput } export type AssetCreateOrConnectWithoutPosesInput = { @@ -666,6 +701,7 @@ export type AssetUpdateWithoutPosesInput = { characters?: Prisma.CharacterUpdateManyWithoutImageNestedInput equipments?: Prisma.EquipmentUpdateManyWithoutImageNestedInput generations?: Prisma.GenerationUpdateManyWithoutImageNestedInput + expressions?: Prisma.ExpressionUpdateManyWithoutImageNestedInput } export type AssetUncheckedUpdateWithoutPosesInput = { @@ -678,6 +714,75 @@ export type AssetUncheckedUpdateWithoutPosesInput = { characters?: Prisma.CharacterUncheckedUpdateManyWithoutImageNestedInput equipments?: Prisma.EquipmentUncheckedUpdateManyWithoutImageNestedInput generations?: Prisma.GenerationUncheckedUpdateManyWithoutImageNestedInput + expressions?: Prisma.ExpressionUncheckedUpdateManyWithoutImageNestedInput +} + +export type AssetCreateWithoutExpressionsInput = { + id: string + name: string + type: string + path: string + createdAt?: Date | string + updatedAt?: Date | string + characters?: Prisma.CharacterCreateNestedManyWithoutImageInput + equipments?: Prisma.EquipmentCreateNestedManyWithoutImageInput + generations?: Prisma.GenerationCreateNestedManyWithoutImageInput + poses?: Prisma.PoseCreateNestedManyWithoutImageInput +} + +export type AssetUncheckedCreateWithoutExpressionsInput = { + id: string + name: string + type: string + path: string + createdAt?: Date | string + updatedAt?: Date | string + characters?: Prisma.CharacterUncheckedCreateNestedManyWithoutImageInput + equipments?: Prisma.EquipmentUncheckedCreateNestedManyWithoutImageInput + generations?: Prisma.GenerationUncheckedCreateNestedManyWithoutImageInput + poses?: Prisma.PoseUncheckedCreateNestedManyWithoutImageInput +} + +export type AssetCreateOrConnectWithoutExpressionsInput = { + where: Prisma.AssetWhereUniqueInput + create: Prisma.XOR +} + +export type AssetUpsertWithoutExpressionsInput = { + update: Prisma.XOR + create: Prisma.XOR + where?: Prisma.AssetWhereInput +} + +export type AssetUpdateToOneWithWhereWithoutExpressionsInput = { + where?: Prisma.AssetWhereInput + data: Prisma.XOR +} + +export type AssetUpdateWithoutExpressionsInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + name?: Prisma.StringFieldUpdateOperationsInput | string + type?: Prisma.StringFieldUpdateOperationsInput | string + path?: Prisma.StringFieldUpdateOperationsInput | string + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + characters?: Prisma.CharacterUpdateManyWithoutImageNestedInput + equipments?: Prisma.EquipmentUpdateManyWithoutImageNestedInput + generations?: Prisma.GenerationUpdateManyWithoutImageNestedInput + poses?: Prisma.PoseUpdateManyWithoutImageNestedInput +} + +export type AssetUncheckedUpdateWithoutExpressionsInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + name?: Prisma.StringFieldUpdateOperationsInput | string + type?: Prisma.StringFieldUpdateOperationsInput | string + path?: Prisma.StringFieldUpdateOperationsInput | string + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + characters?: Prisma.CharacterUncheckedUpdateManyWithoutImageNestedInput + equipments?: Prisma.EquipmentUncheckedUpdateManyWithoutImageNestedInput + generations?: Prisma.GenerationUncheckedUpdateManyWithoutImageNestedInput + poses?: Prisma.PoseUncheckedUpdateManyWithoutImageNestedInput } @@ -690,6 +795,7 @@ export type AssetCountOutputType = { equipments: number generations: number poses: number + expressions: number } export type AssetCountOutputTypeSelect = { @@ -697,6 +803,7 @@ export type AssetCountOutputTypeSelect = { + where?: Prisma.ExpressionWhereInput +} + export type AssetSelect = runtime.Types.Extensions.GetSelect<{ id?: boolean @@ -749,6 +863,7 @@ export type AssetSelect generations?: boolean | Prisma.Asset$generationsArgs poses?: boolean | Prisma.Asset$posesArgs + expressions?: boolean | Prisma.Asset$expressionsArgs _count?: boolean | Prisma.AssetCountOutputTypeDefaultArgs }, ExtArgs["result"]["asset"]> @@ -785,6 +900,7 @@ export type AssetInclude generations?: boolean | Prisma.Asset$generationsArgs poses?: boolean | Prisma.Asset$posesArgs + expressions?: boolean | Prisma.Asset$expressionsArgs _count?: boolean | Prisma.AssetCountOutputTypeDefaultArgs } export type AssetIncludeCreateManyAndReturn = {} @@ -797,6 +913,7 @@ export type $AssetPayload[] generations: Prisma.$GenerationPayload[] poses: Prisma.$PosePayload[] + expressions: Prisma.$ExpressionPayload[] } scalars: runtime.Types.Extensions.GetPayloadResult<{ id: string @@ -1203,6 +1320,7 @@ export interface Prisma__AssetClient = {}>(args?: Prisma.Subset>): Prisma.PrismaPromise, T, "findMany", GlobalOmitOptions> | Null> generations = {}>(args?: Prisma.Subset>): Prisma.PrismaPromise, T, "findMany", GlobalOmitOptions> | Null> poses = {}>(args?: Prisma.Subset>): Prisma.PrismaPromise, T, "findMany", GlobalOmitOptions> | Null> + expressions = {}>(args?: Prisma.Subset>): Prisma.PrismaPromise, T, "findMany", GlobalOmitOptions> | Null> /** * Attaches callbacks for the resolution and/or rejection of the Promise. * @param onfulfilled The callback to execute when the Promise is resolved. @@ -1719,6 +1837,30 @@ export type Asset$posesArgs = { + /** + * Select specific fields to fetch from the Expression + */ + select?: Prisma.ExpressionSelect | null + /** + * Omit specific fields from the Expression + */ + omit?: Prisma.ExpressionOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.ExpressionInclude | null + where?: Prisma.ExpressionWhereInput + orderBy?: Prisma.ExpressionOrderByWithRelationInput | Prisma.ExpressionOrderByWithRelationInput[] + cursor?: Prisma.ExpressionWhereUniqueInput + take?: number + skip?: number + distinct?: Prisma.ExpressionScalarFieldEnum | Prisma.ExpressionScalarFieldEnum[] +} + /** * Asset without action */ diff --git a/src/generated/prisma/models/Expression.ts b/src/generated/prisma/models/Expression.ts new file mode 100644 index 0000000..b587570 --- /dev/null +++ b/src/generated/prisma/models/Expression.ts @@ -0,0 +1,1337 @@ + +/* !!! This is code generated by Prisma. Do not edit directly. !!! */ +/* eslint-disable */ +// biome-ignore-all lint: generated file +// @ts-nocheck +/* + * This file exports the `Expression` model and its related types. + * + * 🟢 You can import this file directly. + */ +import type * as runtime from "@prisma/client/runtime/client" +import type * as $Enums from "../enums.ts" +import type * as Prisma from "../internal/prismaNamespace.ts" + +/** + * Model Expression + * + */ +export type ExpressionModel = runtime.Types.Result.DefaultSelection + +export type AggregateExpression = { + _count: ExpressionCountAggregateOutputType | null + _min: ExpressionMinAggregateOutputType | null + _max: ExpressionMaxAggregateOutputType | null +} + +export type ExpressionMinAggregateOutputType = { + id: string | null + name: string | null + imageId: string | null + createdAt: Date | null + updatedAt: Date | null +} + +export type ExpressionMaxAggregateOutputType = { + id: string | null + name: string | null + imageId: string | null + createdAt: Date | null + updatedAt: Date | null +} + +export type ExpressionCountAggregateOutputType = { + id: number + name: number + imageId: number + createdAt: number + updatedAt: number + _all: number +} + + +export type ExpressionMinAggregateInputType = { + id?: true + name?: true + imageId?: true + createdAt?: true + updatedAt?: true +} + +export type ExpressionMaxAggregateInputType = { + id?: true + name?: true + imageId?: true + createdAt?: true + updatedAt?: true +} + +export type ExpressionCountAggregateInputType = { + id?: true + name?: true + imageId?: true + createdAt?: true + updatedAt?: true + _all?: true +} + +export type ExpressionAggregateArgs = { + /** + * Filter which Expression to aggregate. + */ + where?: Prisma.ExpressionWhereInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/sorting Sorting Docs} + * + * Determine the order of Expressions to fetch. + */ + orderBy?: Prisma.ExpressionOrderByWithRelationInput | Prisma.ExpressionOrderByWithRelationInput[] + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination Cursor Docs} + * + * Sets the start position + */ + cursor?: Prisma.ExpressionWhereUniqueInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Take `±n` Expressions from the position of the cursor. + */ + take?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Skip the first `n` Expressions. + */ + skip?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs} + * + * Count returned Expressions + **/ + _count?: true | ExpressionCountAggregateInputType + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs} + * + * Select which fields to find the minimum value + **/ + _min?: ExpressionMinAggregateInputType + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs} + * + * Select which fields to find the maximum value + **/ + _max?: ExpressionMaxAggregateInputType +} + +export type GetExpressionAggregateType = { + [P in keyof T & keyof AggregateExpression]: P extends '_count' | 'count' + ? T[P] extends true + ? number + : Prisma.GetScalarType + : Prisma.GetScalarType +} + + + + +export type ExpressionGroupByArgs = { + where?: Prisma.ExpressionWhereInput + orderBy?: Prisma.ExpressionOrderByWithAggregationInput | Prisma.ExpressionOrderByWithAggregationInput[] + by: Prisma.ExpressionScalarFieldEnum[] | Prisma.ExpressionScalarFieldEnum + having?: Prisma.ExpressionScalarWhereWithAggregatesInput + take?: number + skip?: number + _count?: ExpressionCountAggregateInputType | true + _min?: ExpressionMinAggregateInputType + _max?: ExpressionMaxAggregateInputType +} + +export type ExpressionGroupByOutputType = { + id: string + name: string + imageId: string + createdAt: Date + updatedAt: Date + _count: ExpressionCountAggregateOutputType | null + _min: ExpressionMinAggregateOutputType | null + _max: ExpressionMaxAggregateOutputType | null +} + +type GetExpressionGroupByPayload = Prisma.PrismaPromise< + Array< + Prisma.PickEnumerable & + { + [P in ((keyof T) & (keyof ExpressionGroupByOutputType))]: P extends '_count' + ? T[P] extends boolean + ? number + : Prisma.GetScalarType + : Prisma.GetScalarType + } + > + > + + + +export type ExpressionWhereInput = { + AND?: Prisma.ExpressionWhereInput | Prisma.ExpressionWhereInput[] + OR?: Prisma.ExpressionWhereInput[] + NOT?: Prisma.ExpressionWhereInput | Prisma.ExpressionWhereInput[] + id?: Prisma.StringFilter<"Expression"> | string + name?: Prisma.StringFilter<"Expression"> | string + imageId?: Prisma.StringFilter<"Expression"> | string + createdAt?: Prisma.DateTimeFilter<"Expression"> | Date | string + updatedAt?: Prisma.DateTimeFilter<"Expression"> | Date | string + image?: Prisma.XOR +} + +export type ExpressionOrderByWithRelationInput = { + id?: Prisma.SortOrder + name?: Prisma.SortOrder + imageId?: Prisma.SortOrder + createdAt?: Prisma.SortOrder + updatedAt?: Prisma.SortOrder + image?: Prisma.AssetOrderByWithRelationInput +} + +export type ExpressionWhereUniqueInput = Prisma.AtLeast<{ + id?: string + AND?: Prisma.ExpressionWhereInput | Prisma.ExpressionWhereInput[] + OR?: Prisma.ExpressionWhereInput[] + NOT?: Prisma.ExpressionWhereInput | Prisma.ExpressionWhereInput[] + name?: Prisma.StringFilter<"Expression"> | string + imageId?: Prisma.StringFilter<"Expression"> | string + createdAt?: Prisma.DateTimeFilter<"Expression"> | Date | string + updatedAt?: Prisma.DateTimeFilter<"Expression"> | Date | string + image?: Prisma.XOR +}, "id"> + +export type ExpressionOrderByWithAggregationInput = { + id?: Prisma.SortOrder + name?: Prisma.SortOrder + imageId?: Prisma.SortOrder + createdAt?: Prisma.SortOrder + updatedAt?: Prisma.SortOrder + _count?: Prisma.ExpressionCountOrderByAggregateInput + _max?: Prisma.ExpressionMaxOrderByAggregateInput + _min?: Prisma.ExpressionMinOrderByAggregateInput +} + +export type ExpressionScalarWhereWithAggregatesInput = { + AND?: Prisma.ExpressionScalarWhereWithAggregatesInput | Prisma.ExpressionScalarWhereWithAggregatesInput[] + OR?: Prisma.ExpressionScalarWhereWithAggregatesInput[] + NOT?: Prisma.ExpressionScalarWhereWithAggregatesInput | Prisma.ExpressionScalarWhereWithAggregatesInput[] + id?: Prisma.StringWithAggregatesFilter<"Expression"> | string + name?: Prisma.StringWithAggregatesFilter<"Expression"> | string + imageId?: Prisma.StringWithAggregatesFilter<"Expression"> | string + createdAt?: Prisma.DateTimeWithAggregatesFilter<"Expression"> | Date | string + updatedAt?: Prisma.DateTimeWithAggregatesFilter<"Expression"> | Date | string +} + +export type ExpressionCreateInput = { + id: string + name: string + createdAt?: Date | string + updatedAt?: Date | string + image: Prisma.AssetCreateNestedOneWithoutExpressionsInput +} + +export type ExpressionUncheckedCreateInput = { + id: string + name: string + imageId: string + createdAt?: Date | string + updatedAt?: Date | string +} + +export type ExpressionUpdateInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + name?: Prisma.StringFieldUpdateOperationsInput | string + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + image?: Prisma.AssetUpdateOneRequiredWithoutExpressionsNestedInput +} + +export type ExpressionUncheckedUpdateInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + name?: Prisma.StringFieldUpdateOperationsInput | string + imageId?: Prisma.StringFieldUpdateOperationsInput | string + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string +} + +export type ExpressionCreateManyInput = { + id: string + name: string + imageId: string + createdAt?: Date | string + updatedAt?: Date | string +} + +export type ExpressionUpdateManyMutationInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + name?: Prisma.StringFieldUpdateOperationsInput | string + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string +} + +export type ExpressionUncheckedUpdateManyInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + name?: Prisma.StringFieldUpdateOperationsInput | string + imageId?: Prisma.StringFieldUpdateOperationsInput | string + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string +} + +export type ExpressionListRelationFilter = { + every?: Prisma.ExpressionWhereInput + some?: Prisma.ExpressionWhereInput + none?: Prisma.ExpressionWhereInput +} + +export type ExpressionOrderByRelationAggregateInput = { + _count?: Prisma.SortOrder +} + +export type ExpressionCountOrderByAggregateInput = { + id?: Prisma.SortOrder + name?: Prisma.SortOrder + imageId?: Prisma.SortOrder + createdAt?: Prisma.SortOrder + updatedAt?: Prisma.SortOrder +} + +export type ExpressionMaxOrderByAggregateInput = { + id?: Prisma.SortOrder + name?: Prisma.SortOrder + imageId?: Prisma.SortOrder + createdAt?: Prisma.SortOrder + updatedAt?: Prisma.SortOrder +} + +export type ExpressionMinOrderByAggregateInput = { + id?: Prisma.SortOrder + name?: Prisma.SortOrder + imageId?: Prisma.SortOrder + createdAt?: Prisma.SortOrder + updatedAt?: Prisma.SortOrder +} + +export type ExpressionCreateNestedManyWithoutImageInput = { + create?: Prisma.XOR | Prisma.ExpressionCreateWithoutImageInput[] | Prisma.ExpressionUncheckedCreateWithoutImageInput[] + connectOrCreate?: Prisma.ExpressionCreateOrConnectWithoutImageInput | Prisma.ExpressionCreateOrConnectWithoutImageInput[] + createMany?: Prisma.ExpressionCreateManyImageInputEnvelope + connect?: Prisma.ExpressionWhereUniqueInput | Prisma.ExpressionWhereUniqueInput[] +} + +export type ExpressionUncheckedCreateNestedManyWithoutImageInput = { + create?: Prisma.XOR | Prisma.ExpressionCreateWithoutImageInput[] | Prisma.ExpressionUncheckedCreateWithoutImageInput[] + connectOrCreate?: Prisma.ExpressionCreateOrConnectWithoutImageInput | Prisma.ExpressionCreateOrConnectWithoutImageInput[] + createMany?: Prisma.ExpressionCreateManyImageInputEnvelope + connect?: Prisma.ExpressionWhereUniqueInput | Prisma.ExpressionWhereUniqueInput[] +} + +export type ExpressionUpdateManyWithoutImageNestedInput = { + create?: Prisma.XOR | Prisma.ExpressionCreateWithoutImageInput[] | Prisma.ExpressionUncheckedCreateWithoutImageInput[] + connectOrCreate?: Prisma.ExpressionCreateOrConnectWithoutImageInput | Prisma.ExpressionCreateOrConnectWithoutImageInput[] + upsert?: Prisma.ExpressionUpsertWithWhereUniqueWithoutImageInput | Prisma.ExpressionUpsertWithWhereUniqueWithoutImageInput[] + createMany?: Prisma.ExpressionCreateManyImageInputEnvelope + set?: Prisma.ExpressionWhereUniqueInput | Prisma.ExpressionWhereUniqueInput[] + disconnect?: Prisma.ExpressionWhereUniqueInput | Prisma.ExpressionWhereUniqueInput[] + delete?: Prisma.ExpressionWhereUniqueInput | Prisma.ExpressionWhereUniqueInput[] + connect?: Prisma.ExpressionWhereUniqueInput | Prisma.ExpressionWhereUniqueInput[] + update?: Prisma.ExpressionUpdateWithWhereUniqueWithoutImageInput | Prisma.ExpressionUpdateWithWhereUniqueWithoutImageInput[] + updateMany?: Prisma.ExpressionUpdateManyWithWhereWithoutImageInput | Prisma.ExpressionUpdateManyWithWhereWithoutImageInput[] + deleteMany?: Prisma.ExpressionScalarWhereInput | Prisma.ExpressionScalarWhereInput[] +} + +export type ExpressionUncheckedUpdateManyWithoutImageNestedInput = { + create?: Prisma.XOR | Prisma.ExpressionCreateWithoutImageInput[] | Prisma.ExpressionUncheckedCreateWithoutImageInput[] + connectOrCreate?: Prisma.ExpressionCreateOrConnectWithoutImageInput | Prisma.ExpressionCreateOrConnectWithoutImageInput[] + upsert?: Prisma.ExpressionUpsertWithWhereUniqueWithoutImageInput | Prisma.ExpressionUpsertWithWhereUniqueWithoutImageInput[] + createMany?: Prisma.ExpressionCreateManyImageInputEnvelope + set?: Prisma.ExpressionWhereUniqueInput | Prisma.ExpressionWhereUniqueInput[] + disconnect?: Prisma.ExpressionWhereUniqueInput | Prisma.ExpressionWhereUniqueInput[] + delete?: Prisma.ExpressionWhereUniqueInput | Prisma.ExpressionWhereUniqueInput[] + connect?: Prisma.ExpressionWhereUniqueInput | Prisma.ExpressionWhereUniqueInput[] + update?: Prisma.ExpressionUpdateWithWhereUniqueWithoutImageInput | Prisma.ExpressionUpdateWithWhereUniqueWithoutImageInput[] + updateMany?: Prisma.ExpressionUpdateManyWithWhereWithoutImageInput | Prisma.ExpressionUpdateManyWithWhereWithoutImageInput[] + deleteMany?: Prisma.ExpressionScalarWhereInput | Prisma.ExpressionScalarWhereInput[] +} + +export type ExpressionCreateWithoutImageInput = { + id: string + name: string + createdAt?: Date | string + updatedAt?: Date | string +} + +export type ExpressionUncheckedCreateWithoutImageInput = { + id: string + name: string + createdAt?: Date | string + updatedAt?: Date | string +} + +export type ExpressionCreateOrConnectWithoutImageInput = { + where: Prisma.ExpressionWhereUniqueInput + create: Prisma.XOR +} + +export type ExpressionCreateManyImageInputEnvelope = { + data: Prisma.ExpressionCreateManyImageInput | Prisma.ExpressionCreateManyImageInput[] +} + +export type ExpressionUpsertWithWhereUniqueWithoutImageInput = { + where: Prisma.ExpressionWhereUniqueInput + update: Prisma.XOR + create: Prisma.XOR +} + +export type ExpressionUpdateWithWhereUniqueWithoutImageInput = { + where: Prisma.ExpressionWhereUniqueInput + data: Prisma.XOR +} + +export type ExpressionUpdateManyWithWhereWithoutImageInput = { + where: Prisma.ExpressionScalarWhereInput + data: Prisma.XOR +} + +export type ExpressionScalarWhereInput = { + AND?: Prisma.ExpressionScalarWhereInput | Prisma.ExpressionScalarWhereInput[] + OR?: Prisma.ExpressionScalarWhereInput[] + NOT?: Prisma.ExpressionScalarWhereInput | Prisma.ExpressionScalarWhereInput[] + id?: Prisma.StringFilter<"Expression"> | string + name?: Prisma.StringFilter<"Expression"> | string + imageId?: Prisma.StringFilter<"Expression"> | string + createdAt?: Prisma.DateTimeFilter<"Expression"> | Date | string + updatedAt?: Prisma.DateTimeFilter<"Expression"> | Date | string +} + +export type ExpressionCreateManyImageInput = { + id: string + name: string + createdAt?: Date | string + updatedAt?: Date | string +} + +export type ExpressionUpdateWithoutImageInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + name?: Prisma.StringFieldUpdateOperationsInput | string + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string +} + +export type ExpressionUncheckedUpdateWithoutImageInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + name?: Prisma.StringFieldUpdateOperationsInput | string + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string +} + +export type ExpressionUncheckedUpdateManyWithoutImageInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + name?: Prisma.StringFieldUpdateOperationsInput | string + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string +} + + + +export type ExpressionSelect = runtime.Types.Extensions.GetSelect<{ + id?: boolean + name?: boolean + imageId?: boolean + createdAt?: boolean + updatedAt?: boolean + image?: boolean | Prisma.AssetDefaultArgs +}, ExtArgs["result"]["expression"]> + +export type ExpressionSelectCreateManyAndReturn = runtime.Types.Extensions.GetSelect<{ + id?: boolean + name?: boolean + imageId?: boolean + createdAt?: boolean + updatedAt?: boolean + image?: boolean | Prisma.AssetDefaultArgs +}, ExtArgs["result"]["expression"]> + +export type ExpressionSelectUpdateManyAndReturn = runtime.Types.Extensions.GetSelect<{ + id?: boolean + name?: boolean + imageId?: boolean + createdAt?: boolean + updatedAt?: boolean + image?: boolean | Prisma.AssetDefaultArgs +}, ExtArgs["result"]["expression"]> + +export type ExpressionSelectScalar = { + id?: boolean + name?: boolean + imageId?: boolean + createdAt?: boolean + updatedAt?: boolean +} + +export type ExpressionOmit = runtime.Types.Extensions.GetOmit<"id" | "name" | "imageId" | "createdAt" | "updatedAt", ExtArgs["result"]["expression"]> +export type ExpressionInclude = { + image?: boolean | Prisma.AssetDefaultArgs +} +export type ExpressionIncludeCreateManyAndReturn = { + image?: boolean | Prisma.AssetDefaultArgs +} +export type ExpressionIncludeUpdateManyAndReturn = { + image?: boolean | Prisma.AssetDefaultArgs +} + +export type $ExpressionPayload = { + name: "Expression" + objects: { + image: Prisma.$AssetPayload + } + scalars: runtime.Types.Extensions.GetPayloadResult<{ + id: string + name: string + imageId: string + createdAt: Date + updatedAt: Date + }, ExtArgs["result"]["expression"]> + composites: {} +} + +export type ExpressionGetPayload = runtime.Types.Result.GetResult + +export type ExpressionCountArgs = + Omit & { + select?: ExpressionCountAggregateInputType | true + } + +export interface ExpressionDelegate { + [K: symbol]: { types: Prisma.TypeMap['model']['Expression'], meta: { name: 'Expression' } } + /** + * Find zero or one Expression that matches the filter. + * @param {ExpressionFindUniqueArgs} args - Arguments to find a Expression + * @example + * // Get one Expression + * const expression = await prisma.expression.findUnique({ + * where: { + * // ... provide filter here + * } + * }) + */ + findUnique(args: Prisma.SelectSubset>): Prisma.Prisma__ExpressionClient, T, "findUnique", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions> + + /** + * Find one Expression that matches the filter or throw an error with `error.code='P2025'` + * if no matches were found. + * @param {ExpressionFindUniqueOrThrowArgs} args - Arguments to find a Expression + * @example + * // Get one Expression + * const expression = await prisma.expression.findUniqueOrThrow({ + * where: { + * // ... provide filter here + * } + * }) + */ + findUniqueOrThrow(args: Prisma.SelectSubset>): Prisma.Prisma__ExpressionClient, T, "findUniqueOrThrow", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + /** + * Find the first Expression that matches the filter. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {ExpressionFindFirstArgs} args - Arguments to find a Expression + * @example + * // Get one Expression + * const expression = await prisma.expression.findFirst({ + * where: { + * // ... provide filter here + * } + * }) + */ + findFirst(args?: Prisma.SelectSubset>): Prisma.Prisma__ExpressionClient, T, "findFirst", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions> + + /** + * Find the first Expression that matches the filter or + * throw `PrismaKnownClientError` with `P2025` code if no matches were found. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {ExpressionFindFirstOrThrowArgs} args - Arguments to find a Expression + * @example + * // Get one Expression + * const expression = await prisma.expression.findFirstOrThrow({ + * where: { + * // ... provide filter here + * } + * }) + */ + findFirstOrThrow(args?: Prisma.SelectSubset>): Prisma.Prisma__ExpressionClient, T, "findFirstOrThrow", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + /** + * Find zero or more Expressions that matches the filter. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {ExpressionFindManyArgs} args - Arguments to filter and select certain fields only. + * @example + * // Get all Expressions + * const expressions = await prisma.expression.findMany() + * + * // Get first 10 Expressions + * const expressions = await prisma.expression.findMany({ take: 10 }) + * + * // Only select the `id` + * const expressionWithIdOnly = await prisma.expression.findMany({ select: { id: true } }) + * + */ + findMany(args?: Prisma.SelectSubset>): Prisma.PrismaPromise, T, "findMany", GlobalOmitOptions>> + + /** + * Create a Expression. + * @param {ExpressionCreateArgs} args - Arguments to create a Expression. + * @example + * // Create one Expression + * const Expression = await prisma.expression.create({ + * data: { + * // ... data to create a Expression + * } + * }) + * + */ + create(args: Prisma.SelectSubset>): Prisma.Prisma__ExpressionClient, T, "create", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + /** + * Create many Expressions. + * @param {ExpressionCreateManyArgs} args - Arguments to create many Expressions. + * @example + * // Create many Expressions + * const expression = await prisma.expression.createMany({ + * data: [ + * // ... provide data here + * ] + * }) + * + */ + createMany(args?: Prisma.SelectSubset>): Prisma.PrismaPromise + + /** + * Create many Expressions and returns the data saved in the database. + * @param {ExpressionCreateManyAndReturnArgs} args - Arguments to create many Expressions. + * @example + * // Create many Expressions + * const expression = await prisma.expression.createManyAndReturn({ + * data: [ + * // ... provide data here + * ] + * }) + * + * // Create many Expressions and only return the `id` + * const expressionWithIdOnly = await prisma.expression.createManyAndReturn({ + * select: { id: true }, + * data: [ + * // ... provide data here + * ] + * }) + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * + */ + createManyAndReturn(args?: Prisma.SelectSubset>): Prisma.PrismaPromise, T, "createManyAndReturn", GlobalOmitOptions>> + + /** + * Delete a Expression. + * @param {ExpressionDeleteArgs} args - Arguments to delete one Expression. + * @example + * // Delete one Expression + * const Expression = await prisma.expression.delete({ + * where: { + * // ... filter to delete one Expression + * } + * }) + * + */ + delete(args: Prisma.SelectSubset>): Prisma.Prisma__ExpressionClient, T, "delete", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + /** + * Update one Expression. + * @param {ExpressionUpdateArgs} args - Arguments to update one Expression. + * @example + * // Update one Expression + * const expression = await prisma.expression.update({ + * where: { + * // ... provide filter here + * }, + * data: { + * // ... provide data here + * } + * }) + * + */ + update(args: Prisma.SelectSubset>): Prisma.Prisma__ExpressionClient, T, "update", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + /** + * Delete zero or more Expressions. + * @param {ExpressionDeleteManyArgs} args - Arguments to filter Expressions to delete. + * @example + * // Delete a few Expressions + * const { count } = await prisma.expression.deleteMany({ + * where: { + * // ... provide filter here + * } + * }) + * + */ + deleteMany(args?: Prisma.SelectSubset>): Prisma.PrismaPromise + + /** + * Update zero or more Expressions. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {ExpressionUpdateManyArgs} args - Arguments to update one or more rows. + * @example + * // Update many Expressions + * const expression = await prisma.expression.updateMany({ + * where: { + * // ... provide filter here + * }, + * data: { + * // ... provide data here + * } + * }) + * + */ + updateMany(args: Prisma.SelectSubset>): Prisma.PrismaPromise + + /** + * Update zero or more Expressions and returns the data updated in the database. + * @param {ExpressionUpdateManyAndReturnArgs} args - Arguments to update many Expressions. + * @example + * // Update many Expressions + * const expression = await prisma.expression.updateManyAndReturn({ + * where: { + * // ... provide filter here + * }, + * data: [ + * // ... provide data here + * ] + * }) + * + * // Update zero or more Expressions and only return the `id` + * const expressionWithIdOnly = await prisma.expression.updateManyAndReturn({ + * select: { id: true }, + * where: { + * // ... provide filter here + * }, + * data: [ + * // ... provide data here + * ] + * }) + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * + */ + updateManyAndReturn(args: Prisma.SelectSubset>): Prisma.PrismaPromise, T, "updateManyAndReturn", GlobalOmitOptions>> + + /** + * Create or update one Expression. + * @param {ExpressionUpsertArgs} args - Arguments to update or create a Expression. + * @example + * // Update or create a Expression + * const expression = await prisma.expression.upsert({ + * create: { + * // ... data to create a Expression + * }, + * update: { + * // ... in case it already exists, update + * }, + * where: { + * // ... the filter for the Expression we want to update + * } + * }) + */ + upsert(args: Prisma.SelectSubset>): Prisma.Prisma__ExpressionClient, T, "upsert", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + + /** + * Count the number of Expressions. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {ExpressionCountArgs} args - Arguments to filter Expressions to count. + * @example + * // Count the number of Expressions + * const count = await prisma.expression.count({ + * where: { + * // ... the filter for the Expressions we want to count + * } + * }) + **/ + count( + args?: Prisma.Subset, + ): Prisma.PrismaPromise< + T extends runtime.Types.Utils.Record<'select', any> + ? T['select'] extends true + ? number + : Prisma.GetScalarType + : number + > + + /** + * Allows you to perform aggregations operations on a Expression. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {ExpressionAggregateArgs} args - Select which aggregations you would like to apply and on what fields. + * @example + * // Ordered by age ascending + * // Where email contains prisma.io + * // Limited to the 10 users + * const aggregations = await prisma.user.aggregate({ + * _avg: { + * age: true, + * }, + * where: { + * email: { + * contains: "prisma.io", + * }, + * }, + * orderBy: { + * age: "asc", + * }, + * take: 10, + * }) + **/ + aggregate(args: Prisma.Subset): Prisma.PrismaPromise> + + /** + * Group by Expression. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {ExpressionGroupByArgs} args - Group by arguments. + * @example + * // Group by city, order by createdAt, get count + * const result = await prisma.user.groupBy({ + * by: ['city', 'createdAt'], + * orderBy: { + * createdAt: true + * }, + * _count: { + * _all: true + * }, + * }) + * + **/ + groupBy< + T extends ExpressionGroupByArgs, + HasSelectOrTake extends Prisma.Or< + Prisma.Extends<'skip', Prisma.Keys>, + Prisma.Extends<'take', Prisma.Keys> + >, + OrderByArg extends Prisma.True extends HasSelectOrTake + ? { orderBy: ExpressionGroupByArgs['orderBy'] } + : { orderBy?: ExpressionGroupByArgs['orderBy'] }, + OrderFields extends Prisma.ExcludeUnderscoreKeys>>, + ByFields extends Prisma.MaybeTupleToUnion, + ByValid extends Prisma.Has, + HavingFields extends Prisma.GetHavingFields, + HavingValid extends Prisma.Has, + ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, + InputErrors extends ByEmpty extends Prisma.True + ? `Error: "by" must not be empty.` + : HavingValid extends Prisma.False + ? { + [P in HavingFields]: P extends ByFields + ? never + : P extends string + ? `Error: Field "${P}" used in "having" needs to be provided in "by".` + : [ + Error, + 'Field ', + P, + ` in "having" needs to be provided in "by"`, + ] + }[HavingFields] + : 'take' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "take", you also need to provide "orderBy"' + : 'skip' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "skip", you also need to provide "orderBy"' + : ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + >(args: Prisma.SubsetIntersection & InputErrors): {} extends InputErrors ? GetExpressionGroupByPayload : Prisma.PrismaPromise +/** + * Fields of the Expression model + */ +readonly fields: ExpressionFieldRefs; +} + +/** + * The delegate class that acts as a "Promise-like" for Expression. + * Why is this prefixed with `Prisma__`? + * Because we want to prevent naming conflicts as mentioned in + * https://github.com/prisma/prisma-client-js/issues/707 + */ +export interface Prisma__ExpressionClient extends Prisma.PrismaPromise { + readonly [Symbol.toStringTag]: "PrismaPromise" + image = {}>(args?: Prisma.Subset>): Prisma.Prisma__AssetClient, T, "findUniqueOrThrow", GlobalOmitOptions> | Null, Null, ExtArgs, GlobalOmitOptions> + /** + * Attaches callbacks for the resolution and/or rejection of the Promise. + * @param onfulfilled The callback to execute when the Promise is resolved. + * @param onrejected The callback to execute when the Promise is rejected. + * @returns A Promise for the completion of which ever callback is executed. + */ + then(onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null): runtime.Types.Utils.JsPromise + /** + * Attaches a callback for only the rejection of the Promise. + * @param onrejected The callback to execute when the Promise is rejected. + * @returns A Promise for the completion of the callback. + */ + catch(onrejected?: ((reason: any) => TResult | PromiseLike) | undefined | null): runtime.Types.Utils.JsPromise + /** + * Attaches a callback that is invoked when the Promise is settled (fulfilled or rejected). The + * resolved value cannot be modified from the callback. + * @param onfinally The callback to execute when the Promise is settled (fulfilled or rejected). + * @returns A Promise for the completion of the callback. + */ + finally(onfinally?: (() => void) | undefined | null): runtime.Types.Utils.JsPromise +} + + + + +/** + * Fields of the Expression model + */ +export interface ExpressionFieldRefs { + readonly id: Prisma.FieldRef<"Expression", 'String'> + readonly name: Prisma.FieldRef<"Expression", 'String'> + readonly imageId: Prisma.FieldRef<"Expression", 'String'> + readonly createdAt: Prisma.FieldRef<"Expression", 'DateTime'> + readonly updatedAt: Prisma.FieldRef<"Expression", 'DateTime'> +} + + +// Custom InputTypes +/** + * Expression findUnique + */ +export type ExpressionFindUniqueArgs = { + /** + * Select specific fields to fetch from the Expression + */ + select?: Prisma.ExpressionSelect | null + /** + * Omit specific fields from the Expression + */ + omit?: Prisma.ExpressionOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.ExpressionInclude | null + /** + * Filter, which Expression to fetch. + */ + where: Prisma.ExpressionWhereUniqueInput +} + +/** + * Expression findUniqueOrThrow + */ +export type ExpressionFindUniqueOrThrowArgs = { + /** + * Select specific fields to fetch from the Expression + */ + select?: Prisma.ExpressionSelect | null + /** + * Omit specific fields from the Expression + */ + omit?: Prisma.ExpressionOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.ExpressionInclude | null + /** + * Filter, which Expression to fetch. + */ + where: Prisma.ExpressionWhereUniqueInput +} + +/** + * Expression findFirst + */ +export type ExpressionFindFirstArgs = { + /** + * Select specific fields to fetch from the Expression + */ + select?: Prisma.ExpressionSelect | null + /** + * Omit specific fields from the Expression + */ + omit?: Prisma.ExpressionOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.ExpressionInclude | null + /** + * Filter, which Expression to fetch. + */ + where?: Prisma.ExpressionWhereInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/sorting Sorting Docs} + * + * Determine the order of Expressions to fetch. + */ + orderBy?: Prisma.ExpressionOrderByWithRelationInput | Prisma.ExpressionOrderByWithRelationInput[] + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination Cursor Docs} + * + * Sets the position for searching for Expressions. + */ + cursor?: Prisma.ExpressionWhereUniqueInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Take `±n` Expressions from the position of the cursor. + */ + take?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Skip the first `n` Expressions. + */ + skip?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/distinct Distinct Docs} + * + * Filter by unique combinations of Expressions. + */ + distinct?: Prisma.ExpressionScalarFieldEnum | Prisma.ExpressionScalarFieldEnum[] +} + +/** + * Expression findFirstOrThrow + */ +export type ExpressionFindFirstOrThrowArgs = { + /** + * Select specific fields to fetch from the Expression + */ + select?: Prisma.ExpressionSelect | null + /** + * Omit specific fields from the Expression + */ + omit?: Prisma.ExpressionOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.ExpressionInclude | null + /** + * Filter, which Expression to fetch. + */ + where?: Prisma.ExpressionWhereInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/sorting Sorting Docs} + * + * Determine the order of Expressions to fetch. + */ + orderBy?: Prisma.ExpressionOrderByWithRelationInput | Prisma.ExpressionOrderByWithRelationInput[] + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination Cursor Docs} + * + * Sets the position for searching for Expressions. + */ + cursor?: Prisma.ExpressionWhereUniqueInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Take `±n` Expressions from the position of the cursor. + */ + take?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Skip the first `n` Expressions. + */ + skip?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/distinct Distinct Docs} + * + * Filter by unique combinations of Expressions. + */ + distinct?: Prisma.ExpressionScalarFieldEnum | Prisma.ExpressionScalarFieldEnum[] +} + +/** + * Expression findMany + */ +export type ExpressionFindManyArgs = { + /** + * Select specific fields to fetch from the Expression + */ + select?: Prisma.ExpressionSelect | null + /** + * Omit specific fields from the Expression + */ + omit?: Prisma.ExpressionOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.ExpressionInclude | null + /** + * Filter, which Expressions to fetch. + */ + where?: Prisma.ExpressionWhereInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/sorting Sorting Docs} + * + * Determine the order of Expressions to fetch. + */ + orderBy?: Prisma.ExpressionOrderByWithRelationInput | Prisma.ExpressionOrderByWithRelationInput[] + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination Cursor Docs} + * + * Sets the position for listing Expressions. + */ + cursor?: Prisma.ExpressionWhereUniqueInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Take `±n` Expressions from the position of the cursor. + */ + take?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Skip the first `n` Expressions. + */ + skip?: number + distinct?: Prisma.ExpressionScalarFieldEnum | Prisma.ExpressionScalarFieldEnum[] +} + +/** + * Expression create + */ +export type ExpressionCreateArgs = { + /** + * Select specific fields to fetch from the Expression + */ + select?: Prisma.ExpressionSelect | null + /** + * Omit specific fields from the Expression + */ + omit?: Prisma.ExpressionOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.ExpressionInclude | null + /** + * The data needed to create a Expression. + */ + data: Prisma.XOR +} + +/** + * Expression createMany + */ +export type ExpressionCreateManyArgs = { + /** + * The data used to create many Expressions. + */ + data: Prisma.ExpressionCreateManyInput | Prisma.ExpressionCreateManyInput[] +} + +/** + * Expression createManyAndReturn + */ +export type ExpressionCreateManyAndReturnArgs = { + /** + * Select specific fields to fetch from the Expression + */ + select?: Prisma.ExpressionSelectCreateManyAndReturn | null + /** + * Omit specific fields from the Expression + */ + omit?: Prisma.ExpressionOmit | null + /** + * The data used to create many Expressions. + */ + data: Prisma.ExpressionCreateManyInput | Prisma.ExpressionCreateManyInput[] + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.ExpressionIncludeCreateManyAndReturn | null +} + +/** + * Expression update + */ +export type ExpressionUpdateArgs = { + /** + * Select specific fields to fetch from the Expression + */ + select?: Prisma.ExpressionSelect | null + /** + * Omit specific fields from the Expression + */ + omit?: Prisma.ExpressionOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.ExpressionInclude | null + /** + * The data needed to update a Expression. + */ + data: Prisma.XOR + /** + * Choose, which Expression to update. + */ + where: Prisma.ExpressionWhereUniqueInput +} + +/** + * Expression updateMany + */ +export type ExpressionUpdateManyArgs = { + /** + * The data used to update Expressions. + */ + data: Prisma.XOR + /** + * Filter which Expressions to update + */ + where?: Prisma.ExpressionWhereInput + /** + * Limit how many Expressions to update. + */ + limit?: number +} + +/** + * Expression updateManyAndReturn + */ +export type ExpressionUpdateManyAndReturnArgs = { + /** + * Select specific fields to fetch from the Expression + */ + select?: Prisma.ExpressionSelectUpdateManyAndReturn | null + /** + * Omit specific fields from the Expression + */ + omit?: Prisma.ExpressionOmit | null + /** + * The data used to update Expressions. + */ + data: Prisma.XOR + /** + * Filter which Expressions to update + */ + where?: Prisma.ExpressionWhereInput + /** + * Limit how many Expressions to update. + */ + limit?: number + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.ExpressionIncludeUpdateManyAndReturn | null +} + +/** + * Expression upsert + */ +export type ExpressionUpsertArgs = { + /** + * Select specific fields to fetch from the Expression + */ + select?: Prisma.ExpressionSelect | null + /** + * Omit specific fields from the Expression + */ + omit?: Prisma.ExpressionOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.ExpressionInclude | null + /** + * The filter to search for the Expression to update in case it exists. + */ + where: Prisma.ExpressionWhereUniqueInput + /** + * In case the Expression found by the `where` argument doesn't exist, create a new Expression with this data. + */ + create: Prisma.XOR + /** + * In case the Expression was found with the provided `where` argument, update it with this data. + */ + update: Prisma.XOR +} + +/** + * Expression delete + */ +export type ExpressionDeleteArgs = { + /** + * Select specific fields to fetch from the Expression + */ + select?: Prisma.ExpressionSelect | null + /** + * Omit specific fields from the Expression + */ + omit?: Prisma.ExpressionOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.ExpressionInclude | null + /** + * Filter which Expression to delete. + */ + where: Prisma.ExpressionWhereUniqueInput +} + +/** + * Expression deleteMany + */ +export type ExpressionDeleteManyArgs = { + /** + * Filter which Expressions to delete + */ + where?: Prisma.ExpressionWhereInput + /** + * Limit how many Expressions to delete. + */ + limit?: number +} + +/** + * Expression without action + */ +export type ExpressionDefaultArgs = { + /** + * Select specific fields to fetch from the Expression + */ + select?: Prisma.ExpressionSelect | null + /** + * Omit specific fields from the Expression + */ + omit?: Prisma.ExpressionOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.ExpressionInclude | null +} diff --git a/src/generated/prisma/models/Generation.ts b/src/generated/prisma/models/Generation.ts index d684813..b9004ca 100644 --- a/src/generated/prisma/models/Generation.ts +++ b/src/generated/prisma/models/Generation.ts @@ -30,6 +30,7 @@ export type GenerationMinAggregateOutputType = { imageId: string | null userPrompt: string | null pose: string | null + expression: string | null createdAt: Date | null updatedAt: Date | null } @@ -40,6 +41,7 @@ export type GenerationMaxAggregateOutputType = { imageId: string | null userPrompt: string | null pose: string | null + expression: string | null createdAt: Date | null updatedAt: Date | null } @@ -50,6 +52,7 @@ export type GenerationCountAggregateOutputType = { imageId: number userPrompt: number pose: number + expression: number createdAt: number updatedAt: number _all: number @@ -62,6 +65,7 @@ export type GenerationMinAggregateInputType = { imageId?: true userPrompt?: true pose?: true + expression?: true createdAt?: true updatedAt?: true } @@ -72,6 +76,7 @@ export type GenerationMaxAggregateInputType = { imageId?: true userPrompt?: true pose?: true + expression?: true createdAt?: true updatedAt?: true } @@ -82,6 +87,7 @@ export type GenerationCountAggregateInputType = { imageId?: true userPrompt?: true pose?: true + expression?: true createdAt?: true updatedAt?: true _all?: true @@ -165,6 +171,7 @@ export type GenerationGroupByOutputType = { imageId: string userPrompt: string | null pose: string | null + expression: string | null createdAt: Date updatedAt: Date _count: GenerationCountAggregateOutputType | null @@ -196,6 +203,7 @@ export type GenerationWhereInput = { imageId?: Prisma.StringFilter<"Generation"> | string userPrompt?: Prisma.StringNullableFilter<"Generation"> | string | null pose?: Prisma.StringNullableFilter<"Generation"> | string | null + expression?: Prisma.StringNullableFilter<"Generation"> | string | null createdAt?: Prisma.DateTimeFilter<"Generation"> | Date | string updatedAt?: Prisma.DateTimeFilter<"Generation"> | Date | string character?: Prisma.XOR @@ -209,6 +217,7 @@ export type GenerationOrderByWithRelationInput = { imageId?: Prisma.SortOrder userPrompt?: Prisma.SortOrderInput | Prisma.SortOrder pose?: Prisma.SortOrderInput | Prisma.SortOrder + expression?: Prisma.SortOrderInput | Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder character?: Prisma.CharacterOrderByWithRelationInput @@ -225,6 +234,7 @@ export type GenerationWhereUniqueInput = Prisma.AtLeast<{ imageId?: Prisma.StringFilter<"Generation"> | string userPrompt?: Prisma.StringNullableFilter<"Generation"> | string | null pose?: Prisma.StringNullableFilter<"Generation"> | string | null + expression?: Prisma.StringNullableFilter<"Generation"> | string | null createdAt?: Prisma.DateTimeFilter<"Generation"> | Date | string updatedAt?: Prisma.DateTimeFilter<"Generation"> | Date | string character?: Prisma.XOR @@ -238,6 +248,7 @@ export type GenerationOrderByWithAggregationInput = { imageId?: Prisma.SortOrder userPrompt?: Prisma.SortOrderInput | Prisma.SortOrder pose?: Prisma.SortOrderInput | Prisma.SortOrder + expression?: Prisma.SortOrderInput | Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder _count?: Prisma.GenerationCountOrderByAggregateInput @@ -254,6 +265,7 @@ export type GenerationScalarWhereWithAggregatesInput = { imageId?: Prisma.StringWithAggregatesFilter<"Generation"> | string userPrompt?: Prisma.StringNullableWithAggregatesFilter<"Generation"> | string | null pose?: Prisma.StringNullableWithAggregatesFilter<"Generation"> | string | null + expression?: Prisma.StringNullableWithAggregatesFilter<"Generation"> | string | null createdAt?: Prisma.DateTimeWithAggregatesFilter<"Generation"> | Date | string updatedAt?: Prisma.DateTimeWithAggregatesFilter<"Generation"> | Date | string } @@ -262,6 +274,7 @@ export type GenerationCreateInput = { id: string userPrompt?: string | null pose?: string | null + expression?: string | null createdAt?: Date | string updatedAt?: Date | string character: Prisma.CharacterCreateNestedOneWithoutGenerationsInput @@ -275,6 +288,7 @@ export type GenerationUncheckedCreateInput = { imageId: string userPrompt?: string | null pose?: string | null + expression?: string | null createdAt?: Date | string updatedAt?: Date | string equipments?: Prisma.GenerationEquipmentUncheckedCreateNestedManyWithoutGenerationInput @@ -284,6 +298,7 @@ export type GenerationUpdateInput = { id?: Prisma.StringFieldUpdateOperationsInput | string userPrompt?: Prisma.NullableStringFieldUpdateOperationsInput | string | null pose?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + expression?: Prisma.NullableStringFieldUpdateOperationsInput | string | null createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string character?: Prisma.CharacterUpdateOneRequiredWithoutGenerationsNestedInput @@ -297,6 +312,7 @@ export type GenerationUncheckedUpdateInput = { imageId?: Prisma.StringFieldUpdateOperationsInput | string userPrompt?: Prisma.NullableStringFieldUpdateOperationsInput | string | null pose?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + expression?: Prisma.NullableStringFieldUpdateOperationsInput | string | null createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string equipments?: Prisma.GenerationEquipmentUncheckedUpdateManyWithoutGenerationNestedInput @@ -308,6 +324,7 @@ export type GenerationCreateManyInput = { imageId: string userPrompt?: string | null pose?: string | null + expression?: string | null createdAt?: Date | string updatedAt?: Date | string } @@ -316,6 +333,7 @@ export type GenerationUpdateManyMutationInput = { id?: Prisma.StringFieldUpdateOperationsInput | string userPrompt?: Prisma.NullableStringFieldUpdateOperationsInput | string | null pose?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + expression?: Prisma.NullableStringFieldUpdateOperationsInput | string | null createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string } @@ -326,6 +344,7 @@ export type GenerationUncheckedUpdateManyInput = { imageId?: Prisma.StringFieldUpdateOperationsInput | string userPrompt?: Prisma.NullableStringFieldUpdateOperationsInput | string | null pose?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + expression?: Prisma.NullableStringFieldUpdateOperationsInput | string | null createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string } @@ -346,6 +365,7 @@ export type GenerationCountOrderByAggregateInput = { imageId?: Prisma.SortOrder userPrompt?: Prisma.SortOrder pose?: Prisma.SortOrder + expression?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder } @@ -356,6 +376,7 @@ export type GenerationMaxOrderByAggregateInput = { imageId?: Prisma.SortOrder userPrompt?: Prisma.SortOrder pose?: Prisma.SortOrder + expression?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder } @@ -366,6 +387,7 @@ export type GenerationMinOrderByAggregateInput = { imageId?: Prisma.SortOrder userPrompt?: Prisma.SortOrder pose?: Prisma.SortOrder + expression?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder } @@ -477,6 +499,7 @@ export type GenerationCreateWithoutImageInput = { id: string userPrompt?: string | null pose?: string | null + expression?: string | null createdAt?: Date | string updatedAt?: Date | string character: Prisma.CharacterCreateNestedOneWithoutGenerationsInput @@ -488,6 +511,7 @@ export type GenerationUncheckedCreateWithoutImageInput = { characterId: string userPrompt?: string | null pose?: string | null + expression?: string | null createdAt?: Date | string updatedAt?: Date | string equipments?: Prisma.GenerationEquipmentUncheckedCreateNestedManyWithoutGenerationInput @@ -527,6 +551,7 @@ export type GenerationScalarWhereInput = { imageId?: Prisma.StringFilter<"Generation"> | string userPrompt?: Prisma.StringNullableFilter<"Generation"> | string | null pose?: Prisma.StringNullableFilter<"Generation"> | string | null + expression?: Prisma.StringNullableFilter<"Generation"> | string | null createdAt?: Prisma.DateTimeFilter<"Generation"> | Date | string updatedAt?: Prisma.DateTimeFilter<"Generation"> | Date | string } @@ -535,6 +560,7 @@ export type GenerationCreateWithoutCharacterInput = { id: string userPrompt?: string | null pose?: string | null + expression?: string | null createdAt?: Date | string updatedAt?: Date | string image: Prisma.AssetCreateNestedOneWithoutGenerationsInput @@ -546,6 +572,7 @@ export type GenerationUncheckedCreateWithoutCharacterInput = { imageId: string userPrompt?: string | null pose?: string | null + expression?: string | null createdAt?: Date | string updatedAt?: Date | string equipments?: Prisma.GenerationEquipmentUncheckedCreateNestedManyWithoutGenerationInput @@ -580,6 +607,7 @@ export type GenerationCreateWithoutEquipmentsInput = { id: string userPrompt?: string | null pose?: string | null + expression?: string | null createdAt?: Date | string updatedAt?: Date | string character: Prisma.CharacterCreateNestedOneWithoutGenerationsInput @@ -592,6 +620,7 @@ export type GenerationUncheckedCreateWithoutEquipmentsInput = { imageId: string userPrompt?: string | null pose?: string | null + expression?: string | null createdAt?: Date | string updatedAt?: Date | string } @@ -616,6 +645,7 @@ export type GenerationUpdateWithoutEquipmentsInput = { id?: Prisma.StringFieldUpdateOperationsInput | string userPrompt?: Prisma.NullableStringFieldUpdateOperationsInput | string | null pose?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + expression?: Prisma.NullableStringFieldUpdateOperationsInput | string | null createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string character?: Prisma.CharacterUpdateOneRequiredWithoutGenerationsNestedInput @@ -628,6 +658,7 @@ export type GenerationUncheckedUpdateWithoutEquipmentsInput = { imageId?: Prisma.StringFieldUpdateOperationsInput | string userPrompt?: Prisma.NullableStringFieldUpdateOperationsInput | string | null pose?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + expression?: Prisma.NullableStringFieldUpdateOperationsInput | string | null createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string } @@ -637,6 +668,7 @@ export type GenerationCreateManyImageInput = { characterId: string userPrompt?: string | null pose?: string | null + expression?: string | null createdAt?: Date | string updatedAt?: Date | string } @@ -645,6 +677,7 @@ export type GenerationUpdateWithoutImageInput = { id?: Prisma.StringFieldUpdateOperationsInput | string userPrompt?: Prisma.NullableStringFieldUpdateOperationsInput | string | null pose?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + expression?: Prisma.NullableStringFieldUpdateOperationsInput | string | null createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string character?: Prisma.CharacterUpdateOneRequiredWithoutGenerationsNestedInput @@ -656,6 +689,7 @@ export type GenerationUncheckedUpdateWithoutImageInput = { characterId?: Prisma.StringFieldUpdateOperationsInput | string userPrompt?: Prisma.NullableStringFieldUpdateOperationsInput | string | null pose?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + expression?: Prisma.NullableStringFieldUpdateOperationsInput | string | null createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string equipments?: Prisma.GenerationEquipmentUncheckedUpdateManyWithoutGenerationNestedInput @@ -666,6 +700,7 @@ export type GenerationUncheckedUpdateManyWithoutImageInput = { characterId?: Prisma.StringFieldUpdateOperationsInput | string userPrompt?: Prisma.NullableStringFieldUpdateOperationsInput | string | null pose?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + expression?: Prisma.NullableStringFieldUpdateOperationsInput | string | null createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string } @@ -675,6 +710,7 @@ export type GenerationCreateManyCharacterInput = { imageId: string userPrompt?: string | null pose?: string | null + expression?: string | null createdAt?: Date | string updatedAt?: Date | string } @@ -683,6 +719,7 @@ export type GenerationUpdateWithoutCharacterInput = { id?: Prisma.StringFieldUpdateOperationsInput | string userPrompt?: Prisma.NullableStringFieldUpdateOperationsInput | string | null pose?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + expression?: Prisma.NullableStringFieldUpdateOperationsInput | string | null createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string image?: Prisma.AssetUpdateOneRequiredWithoutGenerationsNestedInput @@ -694,6 +731,7 @@ export type GenerationUncheckedUpdateWithoutCharacterInput = { imageId?: Prisma.StringFieldUpdateOperationsInput | string userPrompt?: Prisma.NullableStringFieldUpdateOperationsInput | string | null pose?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + expression?: Prisma.NullableStringFieldUpdateOperationsInput | string | null createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string equipments?: Prisma.GenerationEquipmentUncheckedUpdateManyWithoutGenerationNestedInput @@ -704,6 +742,7 @@ export type GenerationUncheckedUpdateManyWithoutCharacterInput = { imageId?: Prisma.StringFieldUpdateOperationsInput | string userPrompt?: Prisma.NullableStringFieldUpdateOperationsInput | string | null pose?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + expression?: Prisma.NullableStringFieldUpdateOperationsInput | string | null createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string } @@ -745,6 +784,7 @@ export type GenerationSelect @@ -759,6 +799,7 @@ export type GenerationSelectCreateManyAndReturn @@ -771,6 +812,7 @@ export type GenerationSelectUpdateManyAndReturn @@ -783,11 +825,12 @@ export type GenerationSelectScalar = { imageId?: boolean userPrompt?: boolean pose?: boolean + expression?: boolean createdAt?: boolean updatedAt?: boolean } -export type GenerationOmit = runtime.Types.Extensions.GetOmit<"id" | "characterId" | "imageId" | "userPrompt" | "pose" | "createdAt" | "updatedAt", ExtArgs["result"]["generation"]> +export type GenerationOmit = runtime.Types.Extensions.GetOmit<"id" | "characterId" | "imageId" | "userPrompt" | "pose" | "expression" | "createdAt" | "updatedAt", ExtArgs["result"]["generation"]> export type GenerationInclude = { character?: boolean | Prisma.CharacterDefaultArgs image?: boolean | Prisma.AssetDefaultArgs @@ -816,6 +859,7 @@ export type $GenerationPayload @@ -1249,6 +1293,7 @@ export interface GenerationFieldRefs { readonly imageId: Prisma.FieldRef<"Generation", 'String'> readonly userPrompt: Prisma.FieldRef<"Generation", 'String'> readonly pose: Prisma.FieldRef<"Generation", 'String'> + readonly expression: Prisma.FieldRef<"Generation", 'String'> readonly createdAt: Prisma.FieldRef<"Generation", 'DateTime'> readonly updatedAt: Prisma.FieldRef<"Generation", 'DateTime'> } diff --git a/src/index.ts b/src/index.ts index da25d93..549175e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,6 +6,7 @@ import asset from './api/asset' import character from './api/character' import equipment from './api/equipment' import extract from './api/extract' +import expression from './api/expression' import generation from './api/generation' import outfit from './api/outfit' import pose from './api/pose' @@ -27,6 +28,7 @@ const route = api .route('/extract', extract) .route('/outfits', outfit) .route('/poses', pose) + .route('/expressions', expression) .route('/settings', setting) // Mount API @@ -38,6 +40,9 @@ app.use('/files/*', serveStatic({ root: './data' })) // Serve static files from public/poses under /poses path app.use('/poses/*', serveStatic({ root: './public' })) +// Serve static files from public/expressions under /expressions path +app.use('/expressions/*', serveStatic({ root: './public' })) + // Export type for RPC export type AppType = typeof route @@ -52,6 +57,7 @@ const server = Bun.serve({ '/api/*': app.fetch, '/files/*': app.fetch, '/poses/*': app.fetch, + '/expressions/*': app.fetch, // Catch-all for SPA routing (fallback to index.html) '/*': index, diff --git a/src/service/expression.ts b/src/service/expression.ts new file mode 100644 index 0000000..42e9553 --- /dev/null +++ b/src/service/expression.ts @@ -0,0 +1,84 @@ +import { ulid } from 'ulidx' +import { prisma } from '../db' +import { assetService } from './asset' + +export interface ExpressionItem { + id: string + name: string + type: 'builtin' | 'custom' + imageUrl: string +} + +export const BUILTIN_EXPRESSIONS: ExpressionItem[] = Array.from({ length: 9 }, (_, i) => i + 1).map( + (i) => ({ + id: `expression_${i}.webp`, + name: `Expression ${i}`, + type: 'builtin', + imageUrl: `/expressions/expression_${i}.webp`, + }), +) + +export class ExpressionService { + async listExpressions(): Promise { + const customExpressions = await prisma.expression.findMany({ + include: { image: true }, + orderBy: { createdAt: 'desc' }, + }) + + const formattedCustomExpressions: ExpressionItem[] = customExpressions.map((e) => ({ + id: e.id, + name: e.name, + type: 'custom', + imageUrl: `/files/${e.image.path}`, + })) + + return [...BUILTIN_EXPRESSIONS, ...formattedCustomExpressions] + } + + async createExpression(name: string, file: File) { + const asset = await assetService.createAsset(file, { + name: name, + type: file.type, + }) + + const expression = await prisma.expression.create({ + data: { + id: ulid(), + name, + imageId: asset.id, + }, + include: { image: true }, + }) + + return { + id: expression.id, + name: expression.name, + type: 'custom', + imageUrl: `/files/${expression.image.path}`, + } as ExpressionItem + } + + async deleteExpression(id: string) { + if (BUILTIN_EXPRESSIONS.some((e) => e.id === id)) { + throw new Error('Cannot delete builtin expression') + } + + const expression = await prisma.expression.findUnique({ + where: { id }, + }) + + if (!expression) { + throw new Error('Expression not found') + } + + await prisma.expression.delete({ + where: { id }, + }) + } + + getBuiltinExpression(id: string) { + return BUILTIN_EXPRESSIONS.find((e) => e.id === id) + } +} + +export const expressionService = new ExpressionService() diff --git a/src/service/generation.ts b/src/service/generation.ts index 3446c60..ba02f15 100644 --- a/src/service/generation.ts +++ b/src/service/generation.ts @@ -4,6 +4,7 @@ import { prisma } from '../db' import { Prisma } from '../generated/prisma/client' import { aiService, type AIPart } from './ai' import { assetService } from './asset' +import { expressionService } from './expression' import { poseService } from './pose' export class GenerationService { @@ -12,6 +13,7 @@ export class GenerationService { equipmentIds: string[], userPrompt?: string, poseId?: string, + expressionId?: string, ) { // 1. Fetch character and its image const character = await prisma.character.findUnique({ @@ -112,6 +114,48 @@ category: ${eq.category} "6. Use the 'Target Pose Reference' image for the character's pose and angle." } + // Handle Expression + let expressionInstruction = '7. Maintain the facial expression of the Base Character.' + + if (expressionId) { + let expressionBuffer: ArrayBuffer + let expressionMimeType: string + + const builtinExpression = expressionService.getBuiltinExpression(expressionId) + if (builtinExpression) { + const expressionPath = join('public/expressions', expressionId) + const file = Bun.file(expressionPath) + expressionBuffer = await file.arrayBuffer() + expressionMimeType = file.type || 'image/webp' + } else { + const customExpression = await prisma.expression.findUnique({ + where: { id: expressionId }, + include: { image: true }, + }) + + if (!customExpression) { + throw new Error(`Expression not found: ${expressionId}`) + } + + const expressionPath = join('data/files', customExpression.image.path) + const file = Bun.file(expressionPath) + expressionBuffer = await file.arrayBuffer() + expressionMimeType = customExpression.image.type + } + + const expressionBase64 = Buffer.from(expressionBuffer).toString('base64') + parts.push({ + inlineData: { + mimeType: expressionMimeType, + data: expressionBase64, + }, + }) + parts.push({ text: 'Target Expression Reference' }) + + expressionInstruction = + "7. Use the 'Target Expression Reference' image for the character's facial expression." + } + let prompt = ` Task: Character Synthesis and Equipment Modification. @@ -121,7 +165,8 @@ category: ${eq.category} 4. The items should replace existing clothing/armor in that slot (e.g. new helmet replaces old hat, armor replaces shirt). 5. Seamlessly blend the items into the character's style. ${poseInstruction} - 7. High quality, detailed, game art style. + ${expressionInstruction} + 8. High quality, detailed, game art style. ` if (userPrompt) { @@ -167,6 +212,7 @@ category: ${eq.category} imageId: asset.id, userPrompt: userPrompt, pose: poseId, + expression: expressionId, }, }) diff --git a/src/ui/App.tsx b/src/ui/App.tsx index ea5c230..3108571 100644 --- a/src/ui/App.tsx +++ b/src/ui/App.tsx @@ -5,6 +5,7 @@ import Characters from './pages/Characters' import Equipments from './pages/Equipments' import FittingRoom from './pages/FittingRoom' import Poses from './pages/Poses' +import Expressions from './pages/Expressions' import Settings from './pages/Settings' export default function App() { @@ -17,6 +18,7 @@ export default function App() { } /> } /> } /> + } /> } /> diff --git a/src/ui/components/AppSidebar.tsx b/src/ui/components/AppSidebar.tsx index cb09e53..3fcf928 100644 --- a/src/ui/components/AppSidebar.tsx +++ b/src/ui/components/AppSidebar.tsx @@ -1,4 +1,4 @@ -import { Backpack, Frame, Settings, Users } from 'lucide-react' +import { Backpack, Frame, Settings, Smile, Users } from 'lucide-react' import { Link, useLocation } from 'react-router-dom' import { Sidebar, @@ -27,6 +27,11 @@ const items = [ url: '/poses', icon: Frame, }, + { + title: 'Expressions', + url: '/expressions', + icon: Smile, + }, { title: 'Settings', url: '/settings', diff --git a/src/ui/components/CreateExpressionDialog.tsx b/src/ui/components/CreateExpressionDialog.tsx new file mode 100644 index 0000000..221d059 --- /dev/null +++ b/src/ui/components/CreateExpressionDialog.tsx @@ -0,0 +1,145 @@ +import { Loader2, Upload } from 'lucide-react' +import React, { useState } from 'react' +import { toast } from 'sonner' +import { client } from '../client' +import { Button } from './ui/button' +import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from './ui/dialog' +import { Input } from './ui/input' +import { Label } from './ui/label' + +interface CreateExpressionDialogProps { + open: boolean + onOpenChange: (open: boolean) => void + onSuccess: () => void +} + +export const CreateExpressionDialog: React.FC = ({ + open, + onOpenChange, + onSuccess, +}) => { + const [name, setName] = useState('') + const [file, setFile] = useState(null) + const [preview, setPreview] = useState(null) + const [loading, setLoading] = useState(false) + + const handleFileChange = (e: React.ChangeEvent) => { + if (e.target.files && e.target.files[0]) { + const f = e.target.files[0] + setFile(f) + setPreview(URL.createObjectURL(f)) + if (!name) { + setName(f.name.replace(/\.[^/.]+$/, '')) + } + } + } + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault() + if (!file || !name) return + + setLoading(true) + + try { + const res = await client.expressions.$post({ + form: { + name, + image: file, + }, + }) + + if (!res.ok) { + throw new Error('Failed to create expression') + } + + toast.success('Expression created successfully') + onSuccess() + handleReset() + onOpenChange(false) + } catch (err) { + console.error(err) + toast.error('Failed to create expression') + } finally { + setLoading(false) + } + } + + const handleReset = () => { + setName('') + setFile(null) + if (preview) URL.revokeObjectURL(preview) + setPreview(null) + } + + return ( + + + + Add Custom Expression + Upload a reference image for a new expression. + +
+
+ +
+ {!preview ? ( + + ) : ( +
+ Preview + +
+ )} +
+
+ +
+ + setName(e.target.value)} + placeholder="Expression Name" + required + /> +
+ +
+ +
+
+
+
+ ) +} diff --git a/src/ui/components/CreateLookDialog.tsx b/src/ui/components/CreateLookDialog.tsx index 86e5d9a..815e42f 100644 --- a/src/ui/components/CreateLookDialog.tsx +++ b/src/ui/components/CreateLookDialog.tsx @@ -1,5 +1,5 @@ import { InferResponseType } from 'hono/client' -import { Check, Download, Loader2, Save, User, X } from 'lucide-react' +import { Check, Download, Loader2, Save, Smile, User, X } from 'lucide-react' import React, { useEffect, useState } from 'react' import { toast } from 'sonner' import { EQUIPMENT_CATEGORIES } from '../../lib/categories' @@ -19,6 +19,8 @@ type EquipmentItem = EquipmentResponse['items'][number] type OutfitItem = InferResponseType[number] type PoseResponse = InferResponseType type PoseItem = PoseResponse[number] +type ExpressionResponse = InferResponseType +type ExpressionItem = ExpressionResponse[number] interface CreateLookDialogProps { open: boolean @@ -39,6 +41,8 @@ export const CreateLookDialog: React.FC = ({ const [selectedEquipments, setSelectedEquipments] = useState([]) const [poses, setPoses] = useState([]) const [selectedPoseId, setSelectedPoseId] = useState(null) + const [expressions, setExpressions] = useState([]) + const [selectedExpressionId, setSelectedExpressionId] = useState(null) const [userPrompt, setUserPrompt] = useState('') const [submitting, setSubmitting] = useState(false) const [error, setError] = useState(null) @@ -50,6 +54,7 @@ export const CreateLookDialog: React.FC = ({ if (open) { fetchItems() fetchPoses() + fetchExpressions() } }, [open, selectedCategories]) @@ -87,6 +92,18 @@ export const CreateLookDialog: React.FC = ({ } } + const fetchExpressions = async () => { + try { + const res = await client.expressions.$get() + if (res.ok) { + const data = await res.json() + setExpressions(data) + } + } catch (e) { + console.error('Failed to load expressions', e) + } + } + const toggleCategory = (category: string) => { setSelectedCategories((prev) => prev.includes(category) ? prev.filter((c) => c !== category) : [...prev, category], @@ -115,6 +132,7 @@ export const CreateLookDialog: React.FC = ({ equipmentIds: selectedEquipments.map((e) => e.id), userPrompt: userPrompt.trim() || undefined, poseId: selectedPoseId || undefined, + expressionId: selectedExpressionId || undefined, }, }) @@ -223,6 +241,59 @@ export const CreateLookDialog: React.FC = ({ + {/* Expression Selection */} +
+
Select Expression
+ +
+
setSelectedExpressionId(null)} + > + + Default +
+ {expressions.map((expression) => { + const isSelected = selectedExpressionId === expression.id + return ( +
setSelectedExpressionId(expression.id)} + > + {expression.name} + {isSelected && ( +
+ +
+ )} +
+ + {expression.name} + +
+
+ ) + })} +
+ +
+
+ {/* Categories */}
diff --git a/src/ui/pages/Expressions.tsx b/src/ui/pages/Expressions.tsx new file mode 100644 index 0000000..9aa55e5 --- /dev/null +++ b/src/ui/pages/Expressions.tsx @@ -0,0 +1,115 @@ +import { InferResponseType } from 'hono/client' +import { Plus, Trash2 } from 'lucide-react' +import { useEffect, useState } from 'react' +import { toast } from 'sonner' +import { client } from '../client' +import { CreateExpressionDialog } from '../components/CreateExpressionDialog' +import { PageHeader } from '../components/PageHeader' +import { VibeCard } from '../components/VibeCard' +import { Button } from '../components/ui/button' + +type ExpressionResponse = InferResponseType +type ExpressionItem = ExpressionResponse[number] + +export default function Expressions() { + const [expressions, setExpressions] = useState([]) + const [loading, setLoading] = useState(true) + const [createOpen, setCreateOpen] = useState(false) + + const fetchExpressions = async () => { + try { + const res = await client.expressions.$get() + if (res.ok) { + const data = await res.json() + setExpressions(data) + } + } catch (e) { + console.error('Failed to load expressions', e) + } finally { + setLoading(false) + } + } + + useEffect(() => { + fetchExpressions() + }, []) + + const handleDelete = async (id: string) => { + if (!confirm('Are you sure you want to delete this expression?')) return + + try { + const res = await client.expressions[':id'].$delete({ param: { id } }) + if (res.ok) { + toast.success('Expression deleted') + fetchExpressions() + } else { + const err = await res.json() + // @ts-ignore + toast.error('Failed to delete: ' + (err.error || 'Unknown error')) + } + } catch { + toast.error('Failed to delete expression') + } + } + + if (loading) { + return ( +
+ INITIALIZING... +
+ ) + } + + return ( +
+ setCreateOpen(true)}> + Add Expression + + } + className="mb-8" + /> + + {expressions.length === 0 ? ( +
+

No expressions found.

+
+ ) : ( +
+ {expressions.map((expression, index) => ( +
+ {}} + /> + {expression.type === 'custom' && ( + + )} +
+ ))} +
+ )} + + +
+ ) +}