Back to Black Site
SOURCE / PINNED RELEASE

Made of little things.

Black Site

Release
666bc7c74ebd…
Author-recorded commit
05e95af79676…
License
LICENSE
Author’s source reference
nostr://npub12lm3rxsva8kfempyjkxupt09e02n3fezurkyadyqfejdc5e0r2kscqty6r/wss%3A%2F%2Fgit.napplet.soy%2F/n-d2225ddc391

Archive hash verified: 1544e072e245c4a8…. The source-to-build association is the author’s claim; it has not been independently rebuilt.

src/customization.ts
import { armoryCatalog } from 'virtual:black-site-catalog';

export type Customization = {
  character: string;
  loadout: { primary: string; secondary: string; throwable: string | null };
  equippedArmor: string | null;
  difficulty: string;
  map: string;
};
function object(value: unknown, keys: string): Record<string, unknown> {
  if (!value || typeof value !== 'object' || Array.isArray(value) || Object.keys(value).sort().join(',') !== keys) throw new Error('customization-invalid');
  return value as Record<string, unknown>;
}
function choice(value: unknown, allowed: string[]): string {
  if (typeof value !== 'string' || !allowed.includes(value)) throw new Error('customization-invalid');
  return value;
}
export function validateCustomization(value: unknown): Customization {
  const data = object(value, 'character,difficulty,equippedArmor,loadout,map');
  const loadout = object(data.loadout, 'primary,secondary,throwable');
  return {
    character: choice(data.character, armoryCatalog.characters),
    loadout: { primary: choice(loadout.primary, armoryCatalog.primary), secondary: choice(loadout.secondary, armoryCatalog.secondary),
      throwable: loadout.throwable === null ? null : choice(loadout.throwable, armoryCatalog.throwables) },
    equippedArmor: data.equippedArmor === null ? null : choice(data.equippedArmor, armoryCatalog.armors),
    difficulty: choice(data.difficulty, armoryCatalog.difficulties), map: choice(data.map, armoryCatalog.maps),
  };
}
export const customizationDigest = (value: Customization) => JSON.stringify(validateCustomization(value));