All files / web/src/lib/arcade practice-approved-games.ts

68.57% Statements 48/70
100% Branches 0/0
0% Functions 0/5
68.57% Lines 48/70

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 711x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x     1x 1x 1x 1x 1x 1x               1x 1x 1x 1x 1x 1x         1x 1x 1x 1x 1x         1x 1x 1x 1x 1x 1x            
/**
 * Practice-Approved Games
 *
 * Determines which games are available for practice session game breaks.
 *
 * A game is available for practice breaks when BOTH conditions are met:
 * 1. The game has `practiceBreakReady: true` in its manifest (game opts in)
 * 2. The game is in the PRACTICE_APPROVED_GAMES whitelist (manual approval)
 *
 * This two-layer approach ensures:
 * - Games must explicitly declare readiness via their manifest
 * - Admins can still control which ready games are actually offered
 */
 
import { getAvailableGames, getGame } from './game-registry'
import type { GameDefinition } from './game-sdk/types'
import { PRACTICE_APPROVED_GAMES } from './practice-approved-game-list'
import type { PracticeApprovedGameName } from './practice-approved-game-list'
 
export { PRACTICE_APPROVED_GAMES, type PracticeApprovedGameName }
 
/**
 * Check if a game name is in the practice whitelist
 */
export function isInPracticeWhitelist(gameName: string): gameName is PracticeApprovedGameName {
  return PRACTICE_APPROVED_GAMES.includes(gameName as PracticeApprovedGameName)
}
 
/**
 * Check if a game is fully approved for practice breaks.
 * Requires BOTH whitelist inclusion AND practiceBreakReady manifest flag.
 */
export function isPracticeApprovedGame(gameName: string): boolean {
  if (!isInPracticeWhitelist(gameName)) return false

  const game = getGame(gameName)
  if (!game) return false

  return game.manifest.practiceBreakReady === true
}
 
/**
 * Get practice-approved games from the registry.
 * Returns only games that are both whitelisted AND have practiceBreakReady: true.
 */
export function getPracticeApprovedGames(): GameDefinition<any, any, any>[] {
  return getAvailableGames().filter(
    (game) => isInPracticeWhitelist(game.manifest.name) && game.manifest.practiceBreakReady === true
  )
}
 
/**
 * Get a random practice-approved game
 */
export function getRandomPracticeApprovedGame(): GameDefinition<any, any, any> | undefined {
  const games = getPracticeApprovedGames()
  if (games.length === 0) return undefined
  return games[Math.floor(Math.random() * games.length)]
}
 
/**
 * Get a specific practice-approved game by name
 * Returns undefined if game is not practice-approved
 */
export function getPracticeApprovedGame(
  gameName: string
): GameDefinition<any, any, any> | undefined {
  if (!isPracticeApprovedGame(gameName)) return undefined
  return getGame(gameName)
}