diff --git a/open-api/openapi.json b/open-api/openapi.json index e6b3c58..db9ba0a 100644 --- a/open-api/openapi.json +++ b/open-api/openapi.json @@ -2340,6 +2340,13 @@ "type": "string" }, "description": "The checkpoint encounter name for each raid activityId, used in lowman tag labels" + }, + "versionCheckpointNames": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "The checkpoint encounter name for each Pantheon versionId, used in lowman tag labels" } }, "required": [ @@ -2361,7 +2368,8 @@ "feats", "splashUrls", "versionSplashUrls", - "checkpointNames" + "checkpointNames", + "versionCheckpointNames" ], "additionalProperties": false }, diff --git a/src/routes/manifest.ts b/src/routes/manifest.ts index f315199..7a50ec1 100644 --- a/src/routes/manifest.ts +++ b/src/routes/manifest.ts @@ -5,7 +5,10 @@ import { zFeatDefinition } from "@/schema/components/FeatDefinition" import { zImageContentData } from "@/schema/components/ImageContentData" import { zVersionDefinition } from "@/schema/components/VersionDefinition" import { zNaturalNumber, zNumericalRecordKey } from "@/schema/output" -import { getCheckpointNamesForRaids } from "@/services/manifest/checkpoint-names" +import { + getCheckpointNamesForRaids, + getVersionCheckpointNames +} from "@/services/manifest/checkpoint-names" import { listActivityDefinitions, listFeatDefinitions, @@ -127,6 +130,10 @@ export const manifestRoute = new RaidHubRoute({ checkpointNames: z.record(zNumericalRecordKey(), z.string()).openapi({ description: "The checkpoint encounter name for each raid activityId, used in lowman tag labels" + }), + versionCheckpointNames: z.record(zNumericalRecordKey(), z.string()).openapi({ + description: + "The checkpoint encounter name for each Pantheon versionId, used in lowman tag labels" }) }) .strict() @@ -172,6 +179,8 @@ export const manifestRoute = new RaidHubRoute({ } }) .map(a => a.id) + const versionDefinitionsById = Object.fromEntries(versions.map(data => [data.id, data])) + const pantheonVersionIdsAll = [...pantheonVersionIds, ...pantheonSunsetVersionIds] return RaidHubRoute.ok({ hashes: Object.fromEntries( @@ -184,7 +193,7 @@ export const manifestRoute = new RaidHubRoute({ ]) ), activityDefinitions: Object.fromEntries(activities.map(data => [data.id, data])), - versionDefinitions: Object.fromEntries(versions.map(data => [data.id, data])), + versionDefinitions: versionDefinitionsById, listedRaidIds, sunsetRaidIds: raids.filter(a => a.isSunset).map(a => a.id), prestigeRaidIds: [ @@ -206,7 +215,11 @@ export const manifestRoute = new RaidHubRoute({ feats: feats, splashUrls: splashUrls, versionSplashUrls: versionSplashUrls, - checkpointNames: getCheckpointNamesForRaids(listedRaidIds) + checkpointNames: getCheckpointNamesForRaids(listedRaidIds), + versionCheckpointNames: getVersionCheckpointNames( + pantheonVersionIdsAll, + versionDefinitionsById + ) }) } }) diff --git a/src/services/manifest/checkpoint-names.test.ts b/src/services/manifest/checkpoint-names.test.ts new file mode 100644 index 0000000..dc9b4c8 --- /dev/null +++ b/src/services/manifest/checkpoint-names.test.ts @@ -0,0 +1,21 @@ +import { expect, test } from "bun:test" +import { getPantheonCheckpointName, getVersionCheckpointNames } from "./checkpoint-names" + +test("getPantheonCheckpointName drops trailing adjective", () => { + expect(getPantheonCheckpointName("Oryx Exalted")).toBe("Oryx") + expect(getPantheonCheckpointName("Atraks Sovereign")).toBe("Atraks") + expect(getPantheonCheckpointName("Morgeth Surpassing")).toBe("Morgeth") + expect(getPantheonCheckpointName("Insurrection Prime Revolutionary")).toBe("Insurrection Prime") +}) + +test("getVersionCheckpointNames maps pantheon version ids", () => { + expect( + getVersionCheckpointNames([129, 134], { + 129: { name: "Oryx Exalted" }, + 134: { name: "Insurrection Prime Revolutionary" } + }) + ).toEqual({ + 129: "Oryx", + 134: "Insurrection Prime" + }) +}) diff --git a/src/services/manifest/checkpoint-names.ts b/src/services/manifest/checkpoint-names.ts index 5c1010b..13c6314 100644 --- a/src/services/manifest/checkpoint-names.ts +++ b/src/services/manifest/checkpoint-names.ts @@ -24,3 +24,32 @@ export const getCheckpointNamesForRaids = (listedRaidIds: readonly number[]) => .map(id => [id, CHECKPOINT_NAMES[id]] as const) .filter((entry): entry is [number, string] => entry[1] != null) ) + +/** Pantheon checkpoint labels drop the trailing difficulty adjective, e.g. "Oryx Exalted" -> "Oryx". */ +export const getPantheonCheckpointName = (versionName: string): string | null => { + const parts = versionName.trim().split(/\s+/).filter(Boolean) + if (parts.length === 0) { + return null + } + if (parts.length === 1) { + return parts[0] + } + return parts.slice(0, -1).join(" ") +} + +export const getVersionCheckpointNames = ( + versionIds: readonly number[], + versionDefinitions: Readonly> +) => + Object.fromEntries( + versionIds + .map(id => { + const versionName = versionDefinitions[id]?.name + if (!versionName) { + return null + } + const checkpointName = getPantheonCheckpointName(versionName) + return checkpointName ? ([id, checkpointName] as const) : null + }) + .filter((entry): entry is [number, string] => entry != null) + )