Initial WallMuse project
This commit is contained in:
101
packages/shared/src/dto/api-management.ts
Executable file
101
packages/shared/src/dto/api-management.ts
Executable file
@@ -0,0 +1,101 @@
|
||||
import { z } from "zod";
|
||||
import { ApiKeyModeSchema, ModelCapabilitySchema, ModelPricingSchema, ModelStatusSchema, ProviderStatusSchema } from "../model-capability";
|
||||
|
||||
export const UserRoleSchema = z.enum(["user", "admin", "super_admin"]);
|
||||
|
||||
export const PublicUserSchema = z.object({
|
||||
id: z.string().uuid(),
|
||||
email: z.string().email(),
|
||||
name: z.string().optional(),
|
||||
roles: z.array(UserRoleSchema),
|
||||
createdAt: z.string().datetime()
|
||||
});
|
||||
|
||||
export const RegisterRequestSchema = z.object({
|
||||
email: z.string().email().max(255),
|
||||
password: z.string().min(8).max(128),
|
||||
name: z.string().min(1).max(80).optional()
|
||||
});
|
||||
|
||||
export const LoginRequestSchema = z.object({
|
||||
email: z.string().email().max(255),
|
||||
password: z.string().min(1).max(128)
|
||||
});
|
||||
|
||||
export const AuthResponseSchema = z.object({
|
||||
user: PublicUserSchema,
|
||||
token: z.string().min(1)
|
||||
});
|
||||
|
||||
export const CreateUserApiKeyRequestSchema = z.object({
|
||||
providerId: z.string().uuid(),
|
||||
name: z.string().min(1).max(80),
|
||||
apiKey: z.string().min(6).max(4096),
|
||||
baseUrl: z.string().url().optional(),
|
||||
defaultModelId: z.string().uuid().optional()
|
||||
});
|
||||
|
||||
export const UserApiKeyResponseSchema = z.object({
|
||||
id: z.string().uuid(),
|
||||
userId: z.string().uuid(),
|
||||
providerId: z.string().uuid(),
|
||||
name: z.string(),
|
||||
maskedKey: z.string(),
|
||||
baseUrl: z.string().url().optional(),
|
||||
defaultModelId: z.string().uuid().optional(),
|
||||
enabled: z.boolean(),
|
||||
createdAt: z.string().datetime(),
|
||||
updatedAt: z.string().datetime()
|
||||
});
|
||||
|
||||
export const CreateProviderRequestSchema = z.object({
|
||||
slug: z.string().min(2).max(80).regex(/^[a-z0-9][a-z0-9-_]*$/),
|
||||
displayName: z.string().min(1).max(120),
|
||||
baseUrl: z.string().url().optional(),
|
||||
authType: z.enum(["bearer", "api_key", "custom"]).default("bearer"),
|
||||
status: ProviderStatusSchema.default("healthy"),
|
||||
keyMode: ApiKeyModeSchema.default("hybrid"),
|
||||
supportsUserKeys: z.boolean().default(true),
|
||||
supportsPlatformKeys: z.boolean().default(true),
|
||||
healthCheckPath: z.string().max(255).optional()
|
||||
});
|
||||
|
||||
export const UpdateProviderRequestSchema = CreateProviderRequestSchema.partial().omit({ slug: true });
|
||||
|
||||
export const CreateModelRequestSchema = z.object({
|
||||
providerId: z.string().uuid(),
|
||||
slug: z.string().min(1).max(160),
|
||||
displayName: z.string().min(1).max(160),
|
||||
status: ModelStatusSchema.default("enabled"),
|
||||
keyMode: ApiKeyModeSchema.default("hybrid"),
|
||||
capability: ModelCapabilitySchema,
|
||||
pricing: ModelPricingSchema.optional(),
|
||||
sortOrder: z.number().int().default(0)
|
||||
});
|
||||
|
||||
export const UpdateModelRequestSchema = CreateModelRequestSchema.partial().omit({ providerId: true });
|
||||
|
||||
export const ProviderCallLogSchema = z.object({
|
||||
id: z.string().uuid(),
|
||||
taskId: z.string().uuid().optional(),
|
||||
providerId: z.string().uuid(),
|
||||
modelId: z.string().uuid().optional(),
|
||||
status: z.enum(["success", "failed"]),
|
||||
latencyMs: z.number().int().nonnegative().optional(),
|
||||
errorCode: z.string().optional(),
|
||||
errorMessage: z.string().optional(),
|
||||
createdAt: z.string().datetime()
|
||||
});
|
||||
|
||||
export type UserRole = z.infer<typeof UserRoleSchema>;
|
||||
export type PublicUser = z.infer<typeof PublicUserSchema>;
|
||||
export type RegisterRequest = z.infer<typeof RegisterRequestSchema>;
|
||||
export type LoginRequest = z.infer<typeof LoginRequestSchema>;
|
||||
export type AuthResponse = z.infer<typeof AuthResponseSchema>;
|
||||
export type CreateUserApiKeyRequest = z.infer<typeof CreateUserApiKeyRequestSchema>;
|
||||
export type UserApiKeyResponse = z.infer<typeof UserApiKeyResponseSchema>;
|
||||
export type CreateProviderRequest = z.infer<typeof CreateProviderRequestSchema>;
|
||||
export type UpdateProviderRequest = z.infer<typeof UpdateProviderRequestSchema>;
|
||||
export type CreateModelRequest = z.infer<typeof CreateModelRequestSchema>;
|
||||
export type UpdateModelRequest = z.infer<typeof UpdateModelRequestSchema>;
|
||||
export type ProviderCallLog = z.infer<typeof ProviderCallLogSchema>;
|
||||
33
packages/shared/src/dto/app-config.ts
Executable file
33
packages/shared/src/dto/app-config.ts
Executable file
@@ -0,0 +1,33 @@
|
||||
import { z } from "zod";
|
||||
import { AspectRatioSchema, ModelSummarySchema, ProviderSummarySchema, ResolutionTierSchema } from "../model-capability";
|
||||
|
||||
export const AppFeatureFlagsSchema = z.object({
|
||||
authEnabled: z.boolean().default(true),
|
||||
galleryEnabled: z.boolean().default(true),
|
||||
userApiKeysEnabled: z.boolean().default(true),
|
||||
generationEnabled: z.boolean().default(true),
|
||||
darkModeEnabled: z.boolean().default(true)
|
||||
});
|
||||
|
||||
export const AppConfigResponseSchema = z.object({
|
||||
site: z.object({
|
||||
name: z.string().default("WallMuse"),
|
||||
tagline: z.string().optional(),
|
||||
logoUrl: z.string().url().optional(),
|
||||
supportEmail: z.string().email().optional()
|
||||
}),
|
||||
generation: z.object({
|
||||
defaultModelId: z.string().uuid().optional(),
|
||||
defaultAspectRatios: z.array(AspectRatioSchema).min(1).default(["16:9", "9:16"]),
|
||||
defaultResolution: ResolutionTierSchema.default("2k"),
|
||||
maxBatchSize: z.number().int().positive().default(4),
|
||||
allowedResolutions: z.array(ResolutionTierSchema).min(1)
|
||||
}),
|
||||
features: AppFeatureFlagsSchema,
|
||||
providers: z.array(ProviderSummarySchema),
|
||||
models: z.array(ModelSummarySchema),
|
||||
updatedAt: z.string().datetime()
|
||||
});
|
||||
|
||||
export type AppFeatureFlags = z.infer<typeof AppFeatureFlagsSchema>;
|
||||
export type AppConfigResponse = z.infer<typeof AppConfigResponseSchema>;
|
||||
84
packages/shared/src/dto/generation.ts
Executable file
84
packages/shared/src/dto/generation.ts
Executable file
@@ -0,0 +1,84 @@
|
||||
import { z } from "zod";
|
||||
import { AspectRatioSchema, GenerationModeSchema, GenerationQualitySchema, ResolutionTierSchema } from "../model-capability";
|
||||
import { GenerationGroupStatusSchema, GenerationTaskStatusSchema } from "../status";
|
||||
|
||||
export const AssetKindSchema = z.enum(["reference", "master", "landscape", "portrait", "thumbnail", "preview", "download_zip"]);
|
||||
export const AssetStatusSchema = z.enum(["temporary", "active", "deleted", "failed"]);
|
||||
export const ModerationStatusSchema = z.enum(["pending", "passed", "rejected", "manual_review"]);
|
||||
|
||||
export const CreateGenerationRequestSchema = z.object({
|
||||
mode: GenerationModeSchema,
|
||||
modelId: z.string().uuid(),
|
||||
prompt: z.string().min(1).max(4000),
|
||||
negativePrompt: z.string().max(2000).optional(),
|
||||
aspectRatios: z.array(AspectRatioSchema).min(1).max(3).default(["16:9", "9:16"]),
|
||||
resolution: ResolutionTierSchema.default("2k"),
|
||||
quality: GenerationQualitySchema.default("standard"),
|
||||
batchSize: z.number().int().min(1).max(8).default(1),
|
||||
seed: z.number().int().optional(),
|
||||
referenceAssetId: z.string().uuid().optional(),
|
||||
stylePresetId: z.string().uuid().optional(),
|
||||
userApiKeyId: z.string().uuid().optional(),
|
||||
publishToGallery: z.boolean().default(false),
|
||||
metadata: z.record(z.unknown()).default({})
|
||||
});
|
||||
|
||||
export const GenerationTaskSchema = z.object({
|
||||
id: z.string().uuid(),
|
||||
groupId: z.string().uuid(),
|
||||
status: GenerationTaskStatusSchema,
|
||||
mode: GenerationModeSchema,
|
||||
aspectRatio: AspectRatioSchema,
|
||||
resolution: ResolutionTierSchema,
|
||||
quality: GenerationQualitySchema,
|
||||
attempt: z.number().int().nonnegative(),
|
||||
maxAttempts: z.number().int().positive(),
|
||||
progress: z.number().int().min(0).max(100),
|
||||
errorCode: z.string().optional(),
|
||||
errorMessage: z.string().optional(),
|
||||
createdAt: z.string().datetime(),
|
||||
updatedAt: z.string().datetime()
|
||||
});
|
||||
|
||||
export const GeneratedAssetSchema = z.object({
|
||||
id: z.string().uuid(),
|
||||
taskId: z.string().uuid().optional(),
|
||||
kind: AssetKindSchema,
|
||||
status: AssetStatusSchema,
|
||||
width: z.number().int().positive().optional(),
|
||||
height: z.number().int().positive().optional(),
|
||||
mimeType: z.string().optional(),
|
||||
publicUrl: z.string().url().optional(),
|
||||
blurHash: z.string().optional(),
|
||||
createdAt: z.string().datetime()
|
||||
});
|
||||
|
||||
export const GenerationGroupSchema = z.object({
|
||||
id: z.string().uuid(),
|
||||
status: GenerationGroupStatusSchema,
|
||||
modelId: z.string().uuid(),
|
||||
prompt: z.string(),
|
||||
negativePrompt: z.string().optional(),
|
||||
tasks: z.array(GenerationTaskSchema),
|
||||
assets: z.array(GeneratedAssetSchema).default([]),
|
||||
createdAt: z.string().datetime(),
|
||||
updatedAt: z.string().datetime()
|
||||
});
|
||||
|
||||
export const CreateGenerationResponseSchema = z.object({
|
||||
generationGroup: GenerationGroupSchema,
|
||||
pollingUrl: z.string().min(1)
|
||||
});
|
||||
|
||||
export const GenerationGroupParamsSchema = z.object({
|
||||
id: z.string().uuid()
|
||||
});
|
||||
|
||||
export type AssetKind = z.infer<typeof AssetKindSchema>;
|
||||
export type AssetStatus = z.infer<typeof AssetStatusSchema>;
|
||||
export type ModerationStatus = z.infer<typeof ModerationStatusSchema>;
|
||||
export type CreateGenerationRequest = z.infer<typeof CreateGenerationRequestSchema>;
|
||||
export type GenerationTask = z.infer<typeof GenerationTaskSchema>;
|
||||
export type GeneratedAsset = z.infer<typeof GeneratedAssetSchema>;
|
||||
export type GenerationGroup = z.infer<typeof GenerationGroupSchema>;
|
||||
export type CreateGenerationResponse = z.infer<typeof CreateGenerationResponseSchema>;
|
||||
92
packages/shared/src/dto/web.ts
Executable file
92
packages/shared/src/dto/web.ts
Executable file
@@ -0,0 +1,92 @@
|
||||
import { z } from "zod";
|
||||
import { AspectRatioSchema, ResolutionTierSchema } from "../model-capability";
|
||||
import { GenerationGroupStatusSchema } from "../status";
|
||||
|
||||
export const ThemePreferenceSchema = z.enum(["system", "light", "dark"]);
|
||||
|
||||
export const WebWallpaperSchema = z.object({
|
||||
id: z.string(),
|
||||
title: z.string(),
|
||||
prompt: z.string(),
|
||||
imageUrl: z.string().url(),
|
||||
ratio: AspectRatioSchema,
|
||||
resolution: ResolutionTierSchema,
|
||||
style: z.string(),
|
||||
model: z.string(),
|
||||
likes: z.number().int().nonnegative(),
|
||||
downloads: z.number().int().nonnegative(),
|
||||
colors: z.array(z.string()),
|
||||
createdAt: z.string().datetime(),
|
||||
featured: z.boolean().optional()
|
||||
});
|
||||
|
||||
export const WebGenerationAssetSchema = z.object({
|
||||
id: z.string(),
|
||||
label: z.enum(["Desktop", "Mobile", "Master"]),
|
||||
ratio: AspectRatioSchema,
|
||||
width: z.number().int().positive(),
|
||||
height: z.number().int().positive(),
|
||||
imageUrl: z.string().url()
|
||||
});
|
||||
|
||||
export const WebGenerationGroupSchema = z.object({
|
||||
id: z.string(),
|
||||
prompt: z.string(),
|
||||
negativePrompt: z.string().optional(),
|
||||
status: GenerationGroupStatusSchema,
|
||||
style: z.string(),
|
||||
model: z.string(),
|
||||
resolution: ResolutionTierSchema,
|
||||
consistencyScore: z.number().int().min(0).max(100),
|
||||
createdAt: z.string().datetime(),
|
||||
assets: z.array(WebGenerationAssetSchema)
|
||||
});
|
||||
|
||||
export const WebUserSchema = z.object({
|
||||
id: z.string(),
|
||||
name: z.string(),
|
||||
email: z.string().email(),
|
||||
avatarInitials: z.string(),
|
||||
theme: ThemePreferenceSchema
|
||||
});
|
||||
|
||||
export const WebUserApiKeySchema = z.object({
|
||||
id: z.string(),
|
||||
provider: z.string(),
|
||||
baseUrl: z.string(),
|
||||
model: z.string(),
|
||||
maskedKey: z.string(),
|
||||
isDefault: z.boolean(),
|
||||
status: z.enum(["untested", "connected", "failed"]),
|
||||
updatedAt: z.string().datetime()
|
||||
});
|
||||
|
||||
export const WebCreateGenerationInputSchema = z.object({
|
||||
mode: z.enum(["text_to_image", "image_to_image"]),
|
||||
prompt: z.string().min(1),
|
||||
negativePrompt: z.string().optional(),
|
||||
style: z.string(),
|
||||
resolution: ResolutionTierSchema,
|
||||
outputPair: z.boolean(),
|
||||
provider: z.string(),
|
||||
model: z.string(),
|
||||
privateMode: z.boolean()
|
||||
});
|
||||
|
||||
export const WebSaveApiKeyInputSchema = z.object({
|
||||
provider: z.string(),
|
||||
baseUrl: z.string().url(),
|
||||
apiKey: z.string().min(1),
|
||||
model: z.string(),
|
||||
saveToAccount: z.boolean(),
|
||||
isDefault: z.boolean()
|
||||
});
|
||||
|
||||
export type ThemePreference = z.infer<typeof ThemePreferenceSchema>;
|
||||
export type WebWallpaper = z.infer<typeof WebWallpaperSchema>;
|
||||
export type WebGenerationAsset = z.infer<typeof WebGenerationAssetSchema>;
|
||||
export type WebGenerationGroup = z.infer<typeof WebGenerationGroupSchema>;
|
||||
export type WebUser = z.infer<typeof WebUserSchema>;
|
||||
export type WebUserApiKey = z.infer<typeof WebUserApiKeySchema>;
|
||||
export type WebCreateGenerationInput = z.infer<typeof WebCreateGenerationInputSchema>;
|
||||
export type WebSaveApiKeyInput = z.infer<typeof WebSaveApiKeyInputSchema>;
|
||||
Reference in New Issue
Block a user