Files
OpenFrontIO/src/core/CosmeticSchemas.ts
T
evanpelle a8945e9ee9 affiliate
2025-09-07 14:26:31 -07:00

74 lines
1.7 KiB
TypeScript

import { base64url } from "jose";
import { z } from "zod/v4";
import { PatternDecoder } from "./PatternDecoder";
export type Cosmetics = z.infer<typeof CosmeticsSchema>;
export type Pattern = z.infer<typeof PatternInfoSchema>;
export type PatternName = z.infer<typeof PatternNameSchema>;
export type Product = z.infer<typeof ProductSchema>;
export const ProductSchema = z.object({
productId: z.string(),
priceId: z.string(),
price: z.string(),
});
export const PatternNameSchema = z
.string()
.regex(/^[a-z0-9_]+$/)
.max(32);
export const PatternSchema = z
.string()
.max(1403)
.base64url()
.refine(
(val) => {
try {
new PatternDecoder(val, base64url.decode);
return true;
} catch (e) {
if (e instanceof Error) {
console.error(JSON.stringify(e.message, null, 2));
} else {
console.error(String(e));
}
return false;
}
},
{
message: "Invalid pattern",
},
);
export const PatternInfoSchema = z.object({
name: PatternNameSchema,
pattern: PatternSchema,
affiliateCode: z.string().nullable(),
product: ProductSchema.nullable(),
});
// Schema for resources/cosmetics/cosmetics.json
export const CosmeticsSchema = z.object({
patterns: z.record(z.string(), PatternInfoSchema),
flag: z
.object({
layers: z.record(
z.string(),
z.object({
name: z.string(),
flares: z.array(z.string()).optional(),
}),
),
color: z.record(
z.string(),
z.object({
color: z.string(),
name: z.string(),
flares: z.array(z.string()).optional(),
}),
),
})
.optional(),
});