Typed client for game configs hosted by Celesty team.
Config types are generated automatically from the live file server.
pnpm add @celesty/configsRequires Node 20+ for the global fetch, or any modern browser. The package is ESM-only and ships no runtime dependencies.
import { ConfigsManager } from '@celesty/configs';
import type { Character } from '@celesty/configs/types';
const configs = new ConfigsManager();
const michele: Character = await configs.fetchCharacter(101);
console.log(michele.profile.name.en);Each collection has three methods and one cache:
await configs.fetchCharacter(101); // one config
await configs.fetchCharacters(); // every config
await configs.listCharacterIds(); // IDs only, no payloads
configs.characters; // Record<number, Character>A fetch method returns the cached config when there is one, and stores the response in the matching cache otherwise, so configs.characters only accumulates the configs you have requested.
The dataset is large - characters alone are a few megabytes each - so prefer fetchCharacter over fetchCharacters unless you genuinely need everything.
const configs = new ConfigsManager({
baseUrl: 'https://staging.files.celesty.one',
fetch: (url, init) => fetch(url, { ...init, headers: { 'X-Trace': '1' } }),
});baseUrl defaults to the FILES_SERVER_URL environment variable where one is exposed, and to https://files.celesty.one otherwise.
Fetch methods take { signal, force }, and the collection-wide ones also take { concurrency }. force replaces the cached copy; clear() empties every cache at once.
Failed requests throw ConfigsHttpError with the url and status fields.
import type { Character, CharacterSkin, TextMap, Quality } from '@celesty/configs/types';All config properties are readonly, and arrays are readonly T[] - the objects you get back are shared with the cache.
A property that is null in some config is typed T | null. A property that is absent from some config is typed T | undefined via ?.
Types recurring across collections are manually added to src/types/shared.ts: TextMap, Locale, Quality, Currency, CurrencyIcons, ItemIconPair, ItemStack, ObtainInfo, ObtainConversion and ObtainSource. Everything else is generated into src/types/generated/, one module per collection.
pnpm generate # download only what changed
pnpm generate --refresh # re-download every config
pnpm generate --offline # read the cache only, issue no requestsConfigs are cached under .cache/configs/ next to a manifest recording the last-modified timestamp each one was downloaded at. A normal run lists the file
server, re-downloads the configs whose timestamp moved, deletes the cached copies of configs the server no longer serves, and reads the rest off disk.
The generator discovers collections by listing /Configs on the file server, so a new folder becomes a new type, a new cache and a new set of methods with no code change. It rewrites src/types/generated/ and src/manager.ts; do NOT edit those files by hand.
Naming follows the layout of the file server:
- A collection is its folder name without the plural
s-Configs/WeaponsbecomesWeapon. Entries ofConfigs/OneFileare single documents holding an ID-to-config map, named the same way. - A nested type is its owning type plus its property name -
Character.profilebecomesCharacterProfile. Array properties lose their plurals, soCharacter.skinsbecomesCharacterSkin. - Properties holding the same set of keys share one type.
defaultSkin,apartmentSkinandskins[]all resolve toCharacterSkin, which also recovers field types that a single position would report as always-null. A merged type is named after the shortest property leading to it, unlessTYPE_NAME_OVERRIDESinscripts/generate/config.tsnames it.
The run reports every merged type, and warns about properties that are null in every config, arrays that are empty in every config, and shapes that nearly - but not exactly - match a shared type. That last check is what prevents a config drifting away from shared.ts.
pnpm install
pnpm typecheck
pnpm buildThe project is licensed under the MIT License - see the LICENSE file for details.