import { z } from 'zod'; import { Prisma } from '../prisma'; ///////////////////////////////////////// // HELPER FUNCTIONS ///////////////////////////////////////// // JSON //------------------------------------------------------ export type NullableJsonInput = Prisma.JsonValue | null | 'JsonNull' | 'DbNull' | Prisma.NullTypes.DbNull | Prisma.NullTypes.JsonNull; export const transformJsonNull = (v?: NullableJsonInput) => { if (!v || v === 'DbNull') return Prisma.DbNull; if (v === 'JsonNull') return Prisma.JsonNull; return v; }; export const JsonValueSchema: z.ZodType = z.lazy(() => z.union([ z.string(), z.number(), z.boolean(), z.literal(null), z.record(z.lazy(() => JsonValueSchema.optional())), z.array(z.lazy(() => JsonValueSchema)), ]) ); export type JsonValueType = z.infer; export const NullableJsonValue = z .union([JsonValueSchema, z.literal('DbNull'), z.literal('JsonNull')]) .nullable() .transform((v) => transformJsonNull(v)); export type NullableJsonValueType = z.infer; export const InputJsonValueSchema: z.ZodType = z.lazy(() => z.union([ z.string(), z.number(), z.boolean(), z.object({ toJSON: z.function(z.tuple([]), z.any()) }), z.record(z.lazy(() => z.union([InputJsonValueSchema, z.literal(null)]))), z.array(z.lazy(() => z.union([InputJsonValueSchema, z.literal(null)]))), ]) ); export type InputJsonValueType = z.infer; // DECIMAL //------------------------------------------------------ export const DecimalJsLikeSchema: z.ZodType = z.object({ d: z.array(z.number()), e: z.number(), s: z.number(), toFixed: z.function(z.tuple([]), z.string()), }) export const DECIMAL_STRING_REGEX = /^(?:-?Infinity|NaN|-?(?:0[bB][01]+(?:\.[01]+)?(?:[pP][-+]?\d+)?|0[oO][0-7]+(?:\.[0-7]+)?(?:[pP][-+]?\d+)?|0[xX][\da-fA-F]+(?:\.[\da-fA-F]+)?(?:[pP][-+]?\d+)?|(?:\d+|\d*\.\d+)(?:[eE][-+]?\d+)?))$/; export const isValidDecimalInput = (v?: null | string | number | Prisma.DecimalJsLike): v is string | number | Prisma.DecimalJsLike => { if (v === undefined || v === null) return false; return ( (typeof v === 'object' && 'd' in v && 'e' in v && 's' in v && 'toFixed' in v) || (typeof v === 'string' && DECIMAL_STRING_REGEX.test(v)) || typeof v === 'number' ) }; ///////////////////////////////////////// // ENUMS ///////////////////////////////////////// export const TransactionIsolationLevelSchema = z.enum(['ReadUncommitted','ReadCommitted','RepeatableRead','Serializable']); export const TelegramSessionScalarFieldEnumSchema = z.enum(['id','data','createdAt','updatedAt']); export const TelegramUserScalarFieldEnumSchema = z.enum(['id','username','isBlocked','firstName','lastName','languageCode','isPremium','createdAt','updatedAt']); export const PaymentScalarFieldEnumSchema = z.enum(['id','telegramUserId','amount','currency','status','provider','providerId','metadata','createdAt','updatedAt']); export const PlanScalarFieldEnumSchema = z.enum(['id','code','name','description','durationDays','dailyGenerations','price','currency']); export const SubscriptionScalarFieldEnumSchema = z.enum(['id','telegramUserId','planId','startedAt','expiresAt','canceledAt','createdAt','updatedAt']); export const SortOrderSchema = z.enum(['asc','desc']); export const JsonNullValueInputSchema = z.enum(['JsonNull',]).transform((value) => (value === 'JsonNull' ? Prisma.JsonNull : value)); export const NullableJsonNullValueInputSchema = z.enum(['DbNull','JsonNull',]).transform((value) => value === 'JsonNull' ? Prisma.JsonNull : value === 'DbNull' ? Prisma.DbNull : value); export const QueryModeSchema = z.enum(['default','insensitive']); export const JsonNullValueFilterSchema = z.enum(['DbNull','JsonNull','AnyNull',]).transform((value) => value === 'JsonNull' ? Prisma.JsonNull : value === 'DbNull' ? Prisma.JsonNull : value === 'AnyNull' ? Prisma.AnyNull : value); export const NullsOrderSchema = z.enum(['first','last']); export const PaymentStatusSchema = z.enum(['PENDING','COMPLETED','FAILED','REFUNDED']); export type PaymentStatusType = `${z.infer}` ///////////////////////////////////////// // MODELS ///////////////////////////////////////// ///////////////////////////////////////// // TELEGRAM SESSION SCHEMA ///////////////////////////////////////// export const TelegramSessionSchema = z.object({ id: z.string(), data: JsonValueSchema, createdAt: z.coerce.date(), updatedAt: z.coerce.date(), }) export type TelegramSession = z.infer ///////////////////////////////////////// // TELEGRAM USER SCHEMA ///////////////////////////////////////// export const TelegramUserSchema = z.object({ id: z.string(), username: z.string().nullable(), isBlocked: z.boolean(), firstName: z.string().nullable(), lastName: z.string().nullable(), languageCode: z.string().nullable(), isPremium: z.boolean().nullable(), createdAt: z.coerce.date(), updatedAt: z.coerce.date(), }) export type TelegramUser = z.infer ///////////////////////////////////////// // PAYMENT SCHEMA ///////////////////////////////////////// export const PaymentSchema = z.object({ status: PaymentStatusSchema, id: z.string().cuid(), telegramUserId: z.string(), amount: z.instanceof(Prisma.Decimal, { message: "Field 'amount' must be a Decimal. Location: ['Models', 'Payment']"}), currency: z.string(), provider: z.string(), providerId: z.string().nullable(), metadata: JsonValueSchema.nullable(), createdAt: z.coerce.date(), updatedAt: z.coerce.date(), }) export type Payment = z.infer ///////////////////////////////////////// // PLAN SCHEMA ///////////////////////////////////////// export const PlanSchema = z.object({ id: z.string().uuid(), code: z.string(), name: z.string(), description: z.string().nullable(), durationDays: z.number().int(), dailyGenerations: z.number().int(), price: z.number().int(), currency: z.string(), }) export type Plan = z.infer ///////////////////////////////////////// // SUBSCRIPTION SCHEMA ///////////////////////////////////////// export const SubscriptionSchema = z.object({ id: z.string().uuid(), telegramUserId: z.string(), planId: z.string(), startedAt: z.coerce.date(), expiresAt: z.coerce.date(), canceledAt: z.coerce.date().nullable(), createdAt: z.coerce.date(), updatedAt: z.coerce.date(), }) export type Subscription = z.infer