/** * Core type definitions for chat-bet-parse * Based on SQL Server schema with TypeScript enhancements */ type Sport = 'Baseball' | 'Basketball' | 'Boxing' | 'Football' | 'Golf' | 'Hockey' | 'MMA' | 'Motor' | 'Politics' | 'Soccer' | 'Tennis'; type League = 'MLB' | 'WNBA' | 'CBK' | 'CBB' | 'NBA' | 'CFL' | 'CFB' | 'NFL' | 'UFL' | 'FCS' | 'LPGA' | 'PGA' | 'NHL' | 'UFC' | 'WTA' | 'ATP'; declare const leagueSportMap: Record; declare const knownLeagues: Set; type KnownLeague = typeof knownLeagues extends Set ? T : never; declare const knownSports: Set; type PeriodTypeCode = 'M' | 'H' | 'Q' | 'I' | 'P'; interface Period { PeriodTypeCode: PeriodTypeCode; PeriodNumber: number; } interface Match { Date?: Date; Team1?: string; Team2?: string; DaySequence?: number; Player?: string; PlayerTeam?: string; } type ContractSportCompetitionMatchType = 'Handicap' | 'TotalPoints' | 'Prop'; type ContestantType = 'Individual' | 'TeamAdHoc' | 'TeamLeague'; /** * Where a contract's Sport came from, strongest first: named in the message * ('explicit'), implied by a league named in the message ('league'), implied * by sport-specific grammar such as innings or "runs" ('grammar'), or guessed * from the rotation-number range ('rotation' — books renumber by season and * reuse numbers, so this is the weakest). Unset when Sport is unset. */ type SportSource = 'explicit' | 'league' | 'grammar' | 'rotation'; interface ContractSportCompetitionMatchBase { Sport?: Sport; SportSource?: SportSource; League?: League; Match: Match; Period: Period; RotationNumber?: number; HasContestant: boolean; HasLine: boolean; ContractSportCompetitionMatchType: ContractSportCompetitionMatchType; } interface ContractSportCompetitionMatchTotalPoints extends ContractSportCompetitionMatchBase { HasContestant: false; HasLine: true; ContractSportCompetitionMatchType: 'TotalPoints'; Line: number; IsOver: boolean; } interface ContractSportCompetitionMatchTotalPointsContestant extends ContractSportCompetitionMatchBase { HasContestant: true; HasLine: true; ContractSportCompetitionMatchType: 'TotalPoints'; Line: number; IsOver: boolean; Contestant: string; } interface ContractSportCompetitionMatchHandicapContestantML extends ContractSportCompetitionMatchBase { HasContestant: true; HasLine: false; ContractSportCompetitionMatchType: 'Handicap'; Contestant: string; TiesLose: boolean; } interface ContractSportCompetitionMatchHandicapContestantLine extends ContractSportCompetitionMatchBase { HasContestant: true; HasLine: true; ContractSportCompetitionMatchType: 'Handicap'; Contestant: string; Line: number; } interface ContractSportCompetitionMatchPropOU extends ContractSportCompetitionMatchBase { HasContestant: true; HasLine: true; ContractSportCompetitionMatchType: 'Prop'; ContestantType?: ContestantType; Prop: string; Contestant: string; Line: number; IsOver: boolean; } interface ContractSportCompetitionMatchPropYN extends ContractSportCompetitionMatchBase { HasContestant: true; HasLine: false; ContractSportCompetitionMatchType: 'Prop'; ContestantType?: ContestantType; Prop: string; Contestant: string; IsYes: boolean; } interface ContractSportCompetitionSeries { Sport?: Sport; SportSource?: SportSource; League?: League; Match: Match; RotationNumber?: number; SeriesLength: number; Contestant: string; } interface ContractWritein { EventDate: Date; Description: string; Sport?: Sport; SportSource?: SportSource; League?: League; } type ContractSportCompetitionMatch = ContractSportCompetitionMatchTotalPoints | ContractSportCompetitionMatchTotalPointsContestant | ContractSportCompetitionMatchHandicapContestantML | ContractSportCompetitionMatchHandicapContestantLine | ContractSportCompetitionMatchPropOU | ContractSportCompetitionMatchPropYN; type Contract = ContractSportCompetitionMatch | ContractSportCompetitionSeries | ContractWritein; type ChatType = 'order' | 'fill'; type BetType = 'straight' | 'parlay' | 'roundRobin'; type ContractType = 'TotalPoints' | 'TotalPointsContestant' | 'HandicapContestantML' | 'HandicapContestantLine' | 'PropOU' | 'PropYN' | 'Series' | 'Writein'; /** * Unified bet structure containing betting amounts and execution details. * * PRIMARY FIELDS (use these): * - Risk/ToWin: Always populated when a size/amount is specified (all bet types) * * DEPRECATED FIELDS (backward compatibility only): * - Price/Size: Use Risk/ToWin instead * * OTHER FIELDS: * - ExecutionDtm: Only for fills (all betTypes) * - IsFreeBet: Optional flag for all types */ interface Bet { Risk?: number; ToWin?: number; /** * @deprecated Use Risk and ToWin instead. This field was only used to calculate * Risk/ToWin, which the library now provides directly. Kept for backward compatibility. */ Price?: number; /** * @deprecated Use Risk and ToWin instead. This field was only used to calculate * Risk/ToWin, which the library now provides directly. Kept for backward compatibility. * Only populated when simple size syntax is used (e.g., "= 2.5"). */ Size?: number; ExecutionDtm?: Date; IsFreeBet?: boolean; } /** * Base interface for all parse results */ interface ParseResultBase { chatType: ChatType; betType: BetType; bet: Bet; } /** * Straight bet (normalized matchup or writein) * Discriminated by betType === 'straight' */ interface ParseResultStraight extends ParseResultBase { betType: 'straight'; contractType: ContractType; contract: Contract; rotationNumber?: number; } /** * Parlay bet (2+ legs combined) * Discriminated by betType === 'parlay' */ interface ParseResultParlay extends ParseResultBase { betType: 'parlay'; useFair: boolean; pushesLose?: boolean; legs: Array; } /** * Round robin bet (Stage 3) * Discriminated by betType === 'roundRobin' */ interface ParseResultRoundRobin extends ParseResultBase { betType: 'roundRobin'; parlaySize: number; isAtMost: boolean; riskType: 'perSelection' | 'total'; useFair: boolean; pushesLose?: boolean; legs: Array; } type ParseResult = ParseResultStraight | ParseResultParlay | ParseResultRoundRobin; interface ParseDiagnostics { rawInput: string; contractText: string; unconsumedText: string; unconsumedTokens: string[]; priceSource: 'explicitAt' | 'standaloneToken' | 'teamGlued' | 'totalGlued' | 'default'; } interface OrderShapeAssessment { kind: 'structured' | 'bareMoneyline'; confidence: 'strong' | 'weak'; reasons: string[]; } interface ParseChatDetailedResult { result: ParseResult; diagnostics: ParseDiagnostics; orderShape: OrderShapeAssessment; } /** @deprecated Use ParseResultStraight with chatType === 'order' instead */ type ChatOrderResult = ParseResultStraight & { chatType: 'order'; }; /** @deprecated Use ParseResultStraight with chatType === 'fill' instead */ type ChatFillResult = ParseResultStraight & { chatType: 'fill'; }; interface ParseOptions { /** * Reference date for year inference logic. * When parsing dates without years (e.g., "7/1" or "MM/DD"), this date is used * to determine whether to use the current year or next year. * Defaults to new Date() (current date/time). */ referenceDate?: Date; /** * Implied chat prefix for unprefixed messages. * When set, a message that does not start with a recognized prefix * (YG/YGW/YGP/YGRR/IW/IWW/IWP/IWRR) is parsed as a straight bet as if the * implied prefix were present ('IW' → order, 'YG' → fill), using the full * existing grammar. Explicit prefixes always take precedence. In 'IW' mode * one additional side-first order pattern is recognized: * "Over 4 first five -105 Red Sox" (side word, line, first-five period * phrase, bare signed American price, trailing team — a single-team GAME * total, the team identifying the event). * Unset by default: unprefixed messages throw UnrecognizedChatPrefixError. */ impliedPrefix?: 'IW' | 'YG'; } declare function isOrder(result: ParseResult): result is ParseResult & { chatType: 'order'; }; declare function isFill(result: ParseResult): result is ParseResult & { chatType: 'fill'; }; declare function isStraight(result: ParseResult): result is ParseResultStraight; declare function isParlay(result: ParseResult): result is ParseResultParlay; declare function isRoundRobin(result: ParseResult): result is ParseResultRoundRobin; declare function isTotalPoints(contract: Contract): contract is ContractSportCompetitionMatchTotalPoints; declare function isTotalPointsContestant(contract: Contract): contract is ContractSportCompetitionMatchTotalPointsContestant; declare function isHandicapML(contract: Contract): contract is ContractSportCompetitionMatchHandicapContestantML; declare function isHandicapLine(contract: Contract): contract is ContractSportCompetitionMatchHandicapContestantLine; declare function isPropOU(contract: Contract): contract is ContractSportCompetitionMatchPropOU; declare function isPropYN(contract: Contract): contract is ContractSportCompetitionMatchPropYN; declare function isSeries(contract: Contract): contract is ContractSportCompetitionSeries; declare function isWritein(contract: Contract): contract is ContractWritein; export { type Bet, type BetType, type ChatFillResult, type ChatOrderResult, type ChatType, type ContestantType, type Contract, type ContractSportCompetitionMatch, type ContractSportCompetitionMatchBase, type ContractSportCompetitionMatchHandicapContestantLine, type ContractSportCompetitionMatchHandicapContestantML, type ContractSportCompetitionMatchPropOU, type ContractSportCompetitionMatchPropYN, type ContractSportCompetitionMatchTotalPoints, type ContractSportCompetitionMatchTotalPointsContestant, type ContractSportCompetitionMatchType, type ContractSportCompetitionSeries, type ContractType, type ContractWritein, type KnownLeague, type League, type Match, type OrderShapeAssessment, type ParseChatDetailedResult, type ParseDiagnostics, type ParseOptions, type ParseResult, type ParseResultBase, type ParseResultParlay, type ParseResultRoundRobin, type ParseResultStraight, type Period, type PeriodTypeCode, type Sport, type SportSource, isFill, isHandicapLine, isHandicapML, isOrder, isParlay, isPropOU, isPropYN, isRoundRobin, isSeries, isStraight, isTotalPoints, isTotalPointsContestant, isWritein, knownLeagues, knownSports, leagueSportMap };