/** 2–80 chars, lowercase letters/digits/`_`/`-`, starting alphanumeric. */ export declare const ACHIEVEMENT_KEY_PATTERN: RegExp; /** * WHO may award the badge — the trust marker a player and the platform UI read. * `platform` is first-party code only; it is in the list because the backend * accepts it, not because a world should use it (see `assertUnlockModeForWorld`). */ export declare const ACHIEVEMENT_UNLOCK_MODES: readonly ["room", "criteria", "platform"]; export type AchievementUnlockMode = (typeof ACHIEVEMENT_UNLOCK_MODES)[number]; export declare const ACHIEVEMENT_CRITERIA_SIGNALS: readonly ["datastore", "iwp", "analytics", "playtime"]; export type AchievementCriteriaSignal = (typeof ACHIEVEMENT_CRITERIA_SIGNALS)[number]; export declare const ACHIEVEMENT_CRITERIA_OPS: readonly ["gte", "lte", "eq"]; export type AchievementCriteriaOp = (typeof ACHIEVEMENT_CRITERIA_OPS)[number]; export declare const ACHIEVEMENT_CRITERIA_METRICS: readonly ["count", "lix"]; export type AchievementCriteriaMetric = (typeof ACHIEVEMENT_CRITERIA_METRICS)[number]; /** * The only two documents a `datastore` criteria may read, and WHICH ONE IS THE * TRUST DECISION: `mp:player:{userId}` is the room's flushed persistent * playerVars (room-only writable ⇒ server-authoritative), `player:{userId}` is * the player's own client-written save (forgeable by its owner, accepted * deliberately — it is how a single-player world unlocks anything). */ export declare const DATA_STORE_CRITERIA_KEY_TEMPLATES: readonly ["player:{userId}", "mp:player:{userId}"]; export type DataStoreCriteriaKeyTemplate = (typeof DATA_STORE_CRITERIA_KEY_TEMPLATES)[number]; /** A `datastore` criteria's `field`: a dot-path of letters, digits and underscores. */ export declare const DATA_STORE_CRITERIA_FIELD_PATTERN: RegExp; /** Backend caps (`ACHIEVEMENT_ICON_MAX_BYTES` / `ACHIEVEMENT_MESH_MAX_BYTES` defaults). */ export declare const ACHIEVEMENT_ICON_MAX_BYTES: number; export declare const ACHIEVEMENT_TROPHY_MAX_BYTES: number; /** Smallest square an icon can be and still read as a graphic on a plaque. */ export declare const MIN_ICON_EDGE = 16; /** * Per-channel standard deviation below which the backend treats an image as one * flat colour. Not zero — a real icon that has been through lossy encoding * carries a little noise. */ export declare const MIN_ICON_STDDEV = 1; export declare const isAchievementKey: (value: unknown) => value is string; /** Content type for the required `image` part — the 2D badge graphic. */ export declare function iconContentTypeFromExtension(file: string): string; /** * What the backend's `assertValidAchievementIcon` checks, mirrored so a * placeholder fails in a second instead of after an upload + a moderation pass. * The two rejections are the two placeholders creators actually send: an image * too small to read, and a single flat colour. Deliberately NOT a quality * judgement — a two-tone glyph or a flat logo on a plate passes. */ export declare function assertIconLooksReal(bytes: Uint8Array, file: string): Promise; export type AchievementCriteria = { signal: AchievementCriteriaSignal; op: AchievementCriteriaOp; value: number; eventName?: string; key?: DataStoreCriteriaKeyTemplate; field?: string; metric?: AchievementCriteriaMetric; }; export type AchievementCriteriaInput = { signal?: string; op?: string; value?: number; eventName?: string; key?: string; field?: string; metric?: string; }; /** True when any criteria field was supplied — i.e. the caller means `criteria`. */ export declare function hasCriteriaInput(input: AchievementCriteriaInput | undefined): boolean; /** * Validate + normalize the criteria the way the backend's `normalizeCriteria` * does, and throw the same failures. Returns the exact object sent as the * multipart `criteria` JSON string — no key the caller did not set. */ export declare function buildAchievementCriteria(input: AchievementCriteriaInput): AchievementCriteria; /** One-line human summary of a stored criteria — the `list` column and the register echo. */ export declare function formatAchievementCriteria(criteria: AchievementCriteria | null | undefined): string; export type AchievementRegistrationInput = { key: string; name: string; description?: string; points?: number; hidden?: boolean; unlockMode?: string; criteria?: AchievementCriteriaInput; }; export type AchievementRegistrationFields = { key: string; name: string; description?: string; points?: number; hidden?: boolean; unlockMode: AchievementUnlockMode; criteria?: AchievementCriteria; }; export type AchievementRegistrationPlan = { fields: AchievementRegistrationFields; warnings: string[]; }; /** * Resolve the trust marker. The backend's DTO defaults to `platform` because the * ADMIN path (worldId omitted) is the one that needs it; for a WORLD * registration `platform` is a mislabel — nothing in a world is first-party * code. So this CLI always sends an explicit mode: `criteria` when a condition * was declared, otherwise `room`, the only thing a world can actually award * (the `awardAchievement` rule effect). */ export declare function resolveUnlockMode(explicit: string | undefined, hasCriteria: boolean): AchievementUnlockMode; /** * Build the multipart text fields, applying every local rule first. Keys the * caller did not set are OMITTED rather than sent empty — an empty description * and no description are the same row, and sending "" would overwrite nothing * while looking like intent. */ export declare function buildAchievementRegistration(input: AchievementRegistrationInput): AchievementRegistrationPlan; export type AchievementUpdateInput = { name?: string; description?: string; points?: number; hidden?: boolean; active?: boolean; }; /** Validate a PATCH body locally and refuse an empty one (a no-op round trip that reads as success). */ export declare function buildAchievementUpdate(input: AchievementUpdateInput): AchievementUpdateInput;