feat : update
CI / Verify (push) Successful in 59s
CI / Build immutable images and deploy (push) Successful in 2m11s

This commit is contained in:
2026-08-29 19:42:28 +00:00 Unverified
parent 1ec145a22e
commit 3f480ac143
9 changed files with 94 additions and 23 deletions
+20
View File
@@ -5,6 +5,7 @@ import {
characterDetailSchema,
cleanLunarisText,
constellationSnapshot,
supportsWeaponType,
} from "@/lib/catalog/lunaris";
describe("Lunaris character data", () => {
@@ -37,4 +38,23 @@ describe("Lunaris character data", () => {
expect(constellationSnapshot(detail, (icon) => icon)).toEqual([]);
});
it("reads the supported weapon type from character details", () => {
const detail = characterDetailSchema.parse({
info: { weapon: "WEAPON_SWORD_ONE_HAND" },
constellations: null,
});
expect(detail.info?.weapon).toBe("WEAPON_SWORD_ONE_HAND");
});
it("matches only weapons supported by the character", () => {
expect(
supportsWeaponType("WEAPON_SWORD_ONE_HAND", "WEAPON_SWORD_ONE_HAND"),
).toBe(true);
expect(
supportsWeaponType("WEAPON_SWORD_ONE_HAND", "WEAPON_CATALYST"),
).toBe(false);
expect(supportsWeaponType(undefined, "WEAPON_SWORD_ONE_HAND")).toBe(false);
});
});
+8
View File
@@ -14,6 +14,7 @@ const constellationSchema = z.object({
});
export const characterDetailSchema = z.object({
info: z.object({ weapon: z.string().optional() }).nullish(),
constellations: z.record(z.string(), constellationSchema).nullish(),
});
@@ -29,6 +30,13 @@ export function avatarIconName(value: string): string {
return value.replace(/^UI_Gacha_AvatarIcon_/u, "UI_AvatarIcon_");
}
export function supportsWeaponType(
characterWeaponType: string | null | undefined,
weaponType: string | null | undefined,
): boolean {
return Boolean(characterWeaponType && characterWeaponType === weaponType);
}
export function constellationSnapshot(
value: z.infer<typeof characterDetailSchema>,
iconKey: (icon: string) => string,
+1 -1
View File
@@ -130,7 +130,7 @@ export async function processCatalogSyncJob(jobId: string): Promise<void> {
const detail = detailRaw ? characterDetailSchema.parse(detailRaw) : null;
const avatarIcon = webpName(avatarIconName(value.CardImg));
return {
version, key, name: value.enName, element: value.element ?? null, rarity: rarity(value.qualityType), weaponType: value.weaponType ?? null,
version, key, name: value.enName, element: value.element ?? null, rarity: rarity(value.qualityType), weaponType: detail?.info?.weapon ?? value.weaponType ?? null,
imageKey: `catalog/${version}/characters/${avatarIcon}`,
sourceImage: `${API_ROOT}/assets/avataricon/${encodeURIComponent(avatarIcon)}`,
constellations: detail ? constellationSnapshot(detail, (icon) => `catalog/${version}/constellations/${webpName(icon)}`) : [],