Spaces:
Sleeping
Sleeping
| import { z } from 'zod'; | |
| /** | |
| * テーマ抽出リクエストスキーマ | |
| */ | |
| export const themeExtractionRequestSchema = z.object({ | |
| url: z.string().url('有効なURLを入力してください'), | |
| provider: z.enum(['openai', 'claude']).default('claude'), | |
| options: z | |
| .object({ | |
| width: z.number().default(512), | |
| height: z.number().default(768), | |
| dummyMode: z.boolean().default(false), | |
| }) | |
| .optional(), | |
| }); | |
| export type ThemeExtractionRequest = z.infer<typeof themeExtractionRequestSchema>; | |
| /** | |
| * カラーテーマスキーマ(15色対応) | |
| */ | |
| export const colorThemeSchema = z.object({ | |
| // メインカラー | |
| primary_color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'カラーコードは#RRGGBBの形式で入力してください'), | |
| secondary_color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'カラーコードは#RRGGBBの形式で入力してください'), | |
| accent_color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'カラーコードは#RRGGBBの形式で入力してください'), | |
| // セマンティックカラー | |
| success_semantic_color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'カラーコードは#RRGGBBの形式で入力してください'), | |
| warning_semantic_color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'カラーコードは#RRGGBBの形式で入力してください'), | |
| error_semantic_color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'カラーコードは#RRGGBBの形式で入力してください'), | |
| info_semantic_color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'カラーコードは#RRGGBBの形式で入力してください'), | |
| // 背景色 | |
| primary_background_color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'カラーコードは#RRGGBBの形式で入力してください'), | |
| secondary_background_color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'カラーコードは#RRGGBBの形式で入力してください'), | |
| tertiary_background_color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'カラーコードは#RRGGBBの形式で入力してください'), | |
| overlay_background_color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'カラーコードは#RRGGBBの形式で入力してください'), | |
| // テキスト色 | |
| primary_text_color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'カラーコードは#RRGGBBの形式で入力してください'), | |
| secondary_text_color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'カラーコードは#RRGGBBの形式で入力してください'), | |
| disabled_text_color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'カラーコードは#RRGGBBの形式で入力してください'), | |
| inverse_text_color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'カラーコードは#RRGGBBの形式で入力してください'), | |
| }); | |
| export type ColorTheme = z.infer<typeof colorThemeSchema>; | |
| /** | |
| * デザイン特性スキーマ(フォントファミリー詳細化対応) | |
| */ | |
| export const designCharacteristicsSchema = z.object({ | |
| // フォントファミリー詳細化 | |
| heading_font_family: z.string(), | |
| main_font_family: z.string(), | |
| special_font_family: z.string(), | |
| // デザイン特性 | |
| design_style: z.string(), | |
| layout_type: z.string(), | |
| }); | |
| export type DesignCharacteristics = z.infer<typeof designCharacteristicsSchema>; | |
| /** | |
| * ブランド印象スキーマ | |
| */ | |
| export const brandImpressionSchema = z.object({ | |
| brand_impression: z.array(z.string()), | |
| industry_characteristics: z.string(), | |
| }); | |
| export type BrandImpression = z.infer<typeof brandImpressionSchema>; | |
| /** | |
| * テーマ抽出結果スキーマ | |
| */ | |
| export const themeExtractionResultSchema = z.object({ | |
| colors: colorThemeSchema, | |
| design: designCharacteristicsSchema, | |
| brand: brandImpressionSchema, | |
| analysis_notes: z.string(), | |
| }); | |
| export type ThemeExtractionResult = z.infer<typeof themeExtractionResultSchema>; | |
| /** | |
| * テーマ抽出レスポンススキーマ | |
| */ | |
| export const themeExtractionResponseSchema = z.object({ | |
| success: z.boolean(), | |
| data: themeExtractionResultSchema.optional(), | |
| error: z.string().optional(), | |
| metadata: z | |
| .object({ | |
| url: z.string(), | |
| provider: z.string(), | |
| processingTime: z.number(), | |
| screenshotTaken: z.boolean(), | |
| timestamp: z.string(), | |
| }) | |
| .optional(), | |
| }); | |
| export type ThemeExtractionResponse = z.infer<typeof themeExtractionResponseSchema>; | |
| /** | |
| * AI応答パース用の中間スキーマ(15色+詳細フォント対応) | |
| */ | |
| export const rawThemeDataSchema = z.object({ | |
| colors: z.object({ | |
| // メインカラー | |
| primary_color: z.string(), | |
| secondary_color: z.string(), | |
| accent_color: z.string(), | |
| // セマンティックカラー | |
| success_semantic_color: z.string(), | |
| warning_semantic_color: z.string(), | |
| error_semantic_color: z.string(), | |
| info_semantic_color: z.string(), | |
| // 背景色 | |
| primary_background_color: z.string(), | |
| secondary_background_color: z.string(), | |
| tertiary_background_color: z.string(), | |
| overlay_background_color: z.string(), | |
| // テキスト色 | |
| primary_text_color: z.string(), | |
| secondary_text_color: z.string(), | |
| disabled_text_color: z.string(), | |
| inverse_text_color: z.string(), | |
| }), | |
| design: z.object({ | |
| // フォントファミリー詳細化 | |
| heading_font_family: z.string(), | |
| main_font_family: z.string(), | |
| special_font_family: z.string(), | |
| // デザイン特性 | |
| design_style: z.string(), | |
| layout_type: z.string(), | |
| }), | |
| brand: z.object({ | |
| brand_impression: z.array(z.string()), | |
| industry_characteristics: z.string(), | |
| }), | |
| analysis_notes: z.string(), | |
| }); | |
| export type RawThemeData = z.infer<typeof rawThemeDataSchema>; | |