126 lines
3.9 KiB
TypeScript
126 lines
3.9 KiB
TypeScript
import { write } from "bun";
|
|
|
|
const API_BASE = "https://eldenring.fanapis.com/api";
|
|
|
|
async function fetchAll(endpoint: string) {
|
|
let allData: any[] = [];
|
|
let page = 0;
|
|
const limit = 100;
|
|
|
|
while (true) {
|
|
const res = await fetch(`${API_BASE}/${endpoint}?limit=${limit}&page=${page}`);
|
|
if (!res.ok) {
|
|
console.error(`Error fetching ${endpoint}:`, res.status);
|
|
break;
|
|
}
|
|
const data = await res.json();
|
|
if (!data.data || data.data.length === 0) {
|
|
break;
|
|
}
|
|
allData = allData.concat(data.data);
|
|
console.log(`Fetched ${allData.length} ${endpoint}...`);
|
|
if (data.data.length < limit) {
|
|
break;
|
|
}
|
|
page++;
|
|
}
|
|
return allData;
|
|
}
|
|
|
|
function extractRegion(entityRegion: string | null | undefined, locationStr: string | null | undefined, locationLookup: Map<string, string>, uniqueRegions: Set<string>): string | null {
|
|
// 1. If the entity has a region, use it (and clean up typos from API)
|
|
if (entityRegion) {
|
|
let r = entityRegion;
|
|
if (r === "Liunia of the Lakes") r = "Liurnia of the Lakes";
|
|
if (r === "Mountaintop of the Giants") r = "Mountaintops of the Giants";
|
|
if (r === "Altus Pleateau") r = "Altus Plateau";
|
|
uniqueRegions.add(r);
|
|
return r;
|
|
}
|
|
|
|
// 2. Lookup via locations map
|
|
if (locationStr) {
|
|
for (const [locName, regionName] of locationLookup.entries()) {
|
|
if (locationStr.toLowerCase().includes(locName.toLowerCase())) {
|
|
return regionName;
|
|
}
|
|
}
|
|
|
|
// 3. Fallback: check if the location string itself contains a known dynamic region
|
|
for (const region of uniqueRegions) {
|
|
if (locationStr.toLowerCase().includes(region.toLowerCase())) {
|
|
return region;
|
|
}
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
async function main() {
|
|
console.log("Fetching locations...");
|
|
const locations = await fetchAll("locations");
|
|
const uniqueRegions = new Set<string>();
|
|
const locationLookup = new Map<string, string>();
|
|
|
|
// Normalize regions and build a lookup map: LocationName -> Region
|
|
for (const loc of locations) {
|
|
if (loc.region) {
|
|
let r = loc.region;
|
|
if (r === "Liunia of the Lakes" || r === "Liurnia") r = "Liurnia of the Lakes";
|
|
if (r === "Mountaintop of the Giants") r = "Mountaintops of the Giants";
|
|
if (r === "Altus Pleateau") r = "Altus Plateau";
|
|
uniqueRegions.add(r);
|
|
locationLookup.set(loc.name, r);
|
|
}
|
|
}
|
|
|
|
console.log("Fetching bosses...");
|
|
const bosses = await fetchAll("bosses");
|
|
|
|
console.log("Fetching creatures...");
|
|
const creatures = await fetchAll("creatures");
|
|
|
|
console.log("Fetching npcs...");
|
|
const npcs = await fetchAll("npcs");
|
|
|
|
const livingEntities = [
|
|
...bosses.map(b => ({ ...b, _type: "boss" })),
|
|
...creatures.map(c => ({ ...c, _type: "creature" })),
|
|
...npcs.map(n => ({ ...n, _type: "npc" }))
|
|
];
|
|
|
|
const cleanedEntities = livingEntities.map(entity => {
|
|
// combine all possible location info
|
|
const cleanRegion = extractRegion(entity.region, entity.location, locationLookup, uniqueRegions);
|
|
|
|
return {
|
|
id: entity.id,
|
|
name: entity.name,
|
|
type: entity._type,
|
|
cleanRegion: cleanRegion || "Unknown",
|
|
originalLocation: entity.location,
|
|
drops: entity.drops || []
|
|
};
|
|
});
|
|
|
|
// Save regions based on what was dynamically found in the API
|
|
const regionsData = Array.from(uniqueRegions).map((r, i) => ({ id: i + 1, name: r }));
|
|
|
|
console.log("Fetching items...");
|
|
const items = await fetchAll("items");
|
|
// you might also want weapons, armors etc depending on what "items" means to the user.
|
|
// The fan API separates items, weapons, armors, etc. Let's just fetch items for now.
|
|
|
|
const output = {
|
|
regions: regionsData,
|
|
entities: cleanedEntities,
|
|
items: items.map(i => ({ id: i.id, name: i.name, type: i.type, effect: i.effect }))
|
|
};
|
|
|
|
await write("./db/fanapi_data.json", JSON.stringify(output, null, 2));
|
|
console.log("Saved to db/fanapi_data.json");
|
|
}
|
|
|
|
main().catch(console.error);
|