UNPKG

chat-bet-parse

Version:

TypeScript package for parsing sports betting contract text into structured data types compatible with SQL Server stored procedures

445 lines (432 loc) 16.6 kB
/** * 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' | 'NBA' | 'CFL' | 'CFB' | 'NFL' | 'UFL' | 'LPGA' | 'PGA' | 'NHL' | 'UFC' | 'WTA' | 'ATP'; type PeriodTypeCode = 'M' | 'H' | 'Q' | 'I' | 'P'; interface Period { PeriodTypeCode: PeriodTypeCode; PeriodNumber: number; } interface Match { Date?: Date; Team1: string; Team2?: string; DaySequence?: number; } type ContractSportCompetitionMatchType = 'Handicap' | 'TotalPoints' | 'Prop'; type ContestantType = 'Individual' | 'TeamAdHoc' | 'TeamLeague'; interface ContractSportCompetitionMatchBase { Sport?: Sport; 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; League?: League; Match: Match; RotationNumber?: number; SeriesLength: number; Contestant: string; } type ContractSportCompetitionMatch = ContractSportCompetitionMatchTotalPoints | ContractSportCompetitionMatchTotalPointsContestant | ContractSportCompetitionMatchHandicapContestantML | ContractSportCompetitionMatchHandicapContestantLine | ContractSportCompetitionMatchPropOU | ContractSportCompetitionMatchPropYN; type Contract = ContractSportCompetitionMatch | ContractSportCompetitionSeries; interface BaseBet { ExecutionDtm?: Date; Price: number; Size?: number; } interface ChatOrder extends BaseBet { Size?: number; } interface ChatFill extends BaseBet { ExecutionDtm: Date; Size: number; } type ChatType = 'order' | 'fill'; type ContractType = 'TotalPoints' | 'TotalPointsContestant' | 'HandicapContestantML' | 'HandicapContestantLine' | 'PropOU' | 'PropYN' | 'Series'; interface ParseResultBase { chatType: ChatType; contractType: ContractType; contract: Contract; rotationNumber?: number; } interface ChatOrderResult extends ParseResultBase { chatType: 'order'; bet: ChatOrder; } interface ChatFillResult extends ParseResultBase { chatType: 'fill'; bet: ChatFill; } type ParseResult = ChatOrderResult | ChatFillResult; declare function isOrder(result: ParseResult): result is ChatOrderResult; declare function isFill(result: ParseResult): result is ChatFillResult; 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; /** * Main parsing engine for chat-bet-parse * Implements the EBNF grammar from README.md */ /** * Parse a chat order (IW message) */ declare function parseChatOrder(message: string): ChatOrderResult; /** * Parse a chat fill (YG message) */ declare function parseChatFill(message: string): ChatFillResult; /** * Main entry point - automatically detects order vs fill */ declare function parseChat(message: string): ParseResult; /** * Error classes for chat-bet-parse * Provides descriptive error messages for parsing failures */ declare class ChatBetParseError extends Error { readonly rawInput: string; position?: number; constructor(message: string, rawInput: string, position?: number); } declare class InvalidChatFormatError extends ChatBetParseError { constructor(rawInput: string, reason: string); } declare class InvalidContractTypeError extends ChatBetParseError { constructor(rawInput: string, contractPortion: string); } declare class InvalidPriceFormatError extends ChatBetParseError { constructor(rawInput: string, priceStr: string); } declare class InvalidSizeFormatError extends ChatBetParseError { constructor(rawInput: string, sizeStr: string, expectedFormat: string); } declare class InvalidLineValueError extends ChatBetParseError { constructor(rawInput: string, line: number); } declare class InvalidTeamFormatError extends ChatBetParseError { constructor(rawInput: string, teamStr: string, reason: string); } declare class InvalidPeriodFormatError extends ChatBetParseError { constructor(rawInput: string, periodStr: string); } declare class InvalidGameNumberError extends ChatBetParseError { constructor(rawInput: string, gameStr: string); } declare class InvalidRotationNumberError extends ChatBetParseError { constructor(rawInput: string, rotationStr: string); } declare class InvalidPropFormatError extends ChatBetParseError { constructor(rawInput: string, propStr: string, availableProps: string[]); } declare class InvalidSeriesLengthError extends ChatBetParseError { constructor(rawInput: string, lengthStr: string); } declare class MissingSizeForFillError extends ChatBetParseError { constructor(rawInput: string); } declare class UnrecognizedChatPrefixError extends ChatBetParseError { constructor(rawInput: string, prefix: string); } declare class AmbiguousContractError extends ChatBetParseError { constructor(rawInput: string, possibleTypes: string[]); } declare function createPositionError(ErrorClass: new (rawInput: string, ...args: any[]) => ChatBetParseError, rawInput: string, position: number, ...args: any[]): ChatBetParseError; /** * Parses USA odds format: +150, -110, -115.5, ev, even */ declare function parsePrice(priceStr: string, rawInput: string): number; type SizeFormat = 'unit' | 'decimal_thousands' | 'k_notation' | 'dollar'; interface ParsedSize { value: number; format: SizeFormat; } /** * Parse size for chat orders (unit interpretation) */ declare function parseOrderSize(sizeStr: string, rawInput: string): ParsedSize; /** * Parse size for chat fills (thousands interpretation for decimals) */ declare function parseFillSize(sizeStr: string, rawInput: string): ParsedSize; /** * Parse betting line - must be divisible by 0.5 */ declare function parseLine(lineStr: string, rawInput: string): number; /** * Parse period according to EBNF grammar */ declare function parsePeriod(periodStr: string, rawInput: string): Period; /** * Parse game number: G2, GM1, #2, etc. */ declare function parseGameNumber(gameStr: string, rawInput: string): number; /** * Parse rotation number (must appear immediately after YG/IW) */ declare function parseRotationNumber(rotationStr: string, rawInput: string): number; /** * Clean and validate team name, with detection for individual contestants */ declare function parseTeam(teamStr: string, rawInput: string): string; /** * Detect if a contestant name is an individual (follows pattern like "B. Falter") */ declare function detectContestantType(contestant: string): ContestantType | undefined; /** * Parse teams string: "Team1/Team2" or just "Team1" */ declare function parseTeams(teamsStr: string, rawInput: string): { team1: string; team2?: string; }; /** * Infer sport and league from context (rotation number, teams, etc.) * This is a simplified version - in practice, you might use rotation number ranges */ declare function inferSportAndLeague(rotationNumber?: number): { sport?: Sport; league?: League; }; /** * Case-insensitive text matching */ declare function matchesIgnoreCase(text: string, pattern: string): boolean; /** * Extract over/under from text: "o4.5" -> { isOver: true, line: 4.5 } */ declare function parseOverUnder(ouStr: string, rawInput: string): { isOver: boolean; line: number; }; type PropCategory = 'PropOU' | 'PropYN'; interface PropTypeInfo { standardName: string; category: PropCategory; } /** * Detect prop type from text and return standardized info */ declare function detectPropType(propText: string): PropTypeInfo | null; /** * Validate prop format based on category */ declare function validatePropFormat(propText: string, hasLine: boolean, rawInput: string): void; /** * Type definitions for chat-bet-parse grading functionality */ /** * The result of grading a contract * W = Win, L = Loss, P = Push (tie), ? = Unable to grade (missing data) */ type GradeResult = 'W' | 'L' | 'P' | '?'; /** * SQL Server connection configuration * Uses the mssql package connection interface */ interface GradingClientConfig { /** SQL Server connection string */ connectionString: string; /** Connection pool configuration (optional) */ pool?: { max?: number; min?: number; idleTimeoutMillis?: number; acquireTimeoutMillis?: number; }; /** Request timeout in milliseconds (default: 30000) */ requestTimeout?: number; /** Connection timeout in milliseconds (default: 15000) */ connectionTimeout?: number; } /** * Interface for grading client */ interface IGradingClient { /** * Grade a parsed chat result * @param result The ParseResult from parseChat() * @param options Optional grading options * @returns Promise resolving to grade ('W', 'L', 'P', or '?') */ grade(result: ParseResult, options?: GradingOptions): Promise<GradeResult>; /** * Test the database connection * @throws Error if connection fails */ testConnection(): Promise<void>; /** * Close the database connection and clean up resources */ close(): Promise<void>; /** * Get connection status */ isConnected(): boolean; } /** * SQL parameters for the universal grading function */ interface GradingSqlParameters { MatchScheduledDate: Date; Contestant1: string; Contestant2?: string; DaySequence?: number; MatchContestantType?: ContestantType; PeriodTypeCode: string; PeriodNumber: number; ContractType: string; Line?: number; IsOver?: boolean; SelectedContestant?: string; TiesLose?: boolean; Prop?: string; PropContestantType?: ContestantType; IsYes?: boolean; SeriesLength?: number; } /** * Base class for grading errors */ declare class GradingError extends Error { readonly originalError?: Error | undefined; constructor(message: string, originalError?: Error | undefined); } /** * Error thrown when database connection fails */ declare class GradingConnectionError extends GradingError { constructor(message: string, originalError?: Error); } /** * Error thrown when SQL query fails */ declare class GradingQueryError extends GradingError { constructor(message: string, originalError?: Error); } /** * Error thrown when contract data is insufficient for grading */ declare class GradingDataError extends GradingError { constructor(message: string); } /** * Options for grading a contract */ interface GradingOptions { /** The scheduled date of the match (defaults to contract date or today) */ matchScheduledDate?: Date; } /** * SQL Server grading client with connection pooling */ /** * SQL Server client for grading parsed chat bets * Supports connection pooling and comprehensive error handling */ declare class ChatBetGradingClient implements IGradingClient { private pool; private isPoolConnected; private readonly connectionString; constructor(config: string | GradingClientConfig); /** * Test the database connection * This will be called automatically on first use, but can be called explicitly */ testConnection(): Promise<void>; /** * Get connection status */ isConnected(): boolean; /** * Grade a parsed chat result */ grade(result: ParseResult, options?: GradingOptions): Promise<GradeResult>; /** * Close the database connection and clean up resources */ close(): Promise<void>; /** * Execute the SQL Server grading function with parameters */ private executeGradingFunction; } /** * Create a new grading client with a connection string */ declare function createGradingClient(connectionString: string): ChatBetGradingClient; /** * Create a new grading client with full configuration */ declare function createGradingClientWithConfig(config: GradingClientConfig): ChatBetGradingClient; /** * Mappers to convert ParseResult contracts to SQL Server function parameters */ /** * Convert a ParseResult to SQL Server function parameters */ declare function mapParseResultToSqlParameters(result: ParseResult, options?: GradingOptions): GradingSqlParameters; /** * Validate that required parameters are present for grading */ declare function validateGradingParameters(params: GradingSqlParameters): void; export { AmbiguousContractError, type BaseBet, ChatBetGradingClient, ChatBetParseError, type ChatFill, type ChatFillResult, type ChatOrder, 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 GradeResult, type GradingClientConfig, GradingConnectionError, GradingDataError, GradingError, GradingQueryError, type GradingSqlParameters, type IGradingClient, InvalidChatFormatError, InvalidContractTypeError, InvalidGameNumberError, InvalidLineValueError, InvalidPeriodFormatError, InvalidPriceFormatError, InvalidPropFormatError, InvalidRotationNumberError, InvalidSeriesLengthError, InvalidSizeFormatError, InvalidTeamFormatError, type League, type Match, MissingSizeForFillError, type ParseResult, type ParseResultBase, type ParsedSize, type Period, type PeriodTypeCode, type PropCategory, type PropTypeInfo, type SizeFormat, type Sport, UnrecognizedChatPrefixError, createGradingClient, createGradingClientWithConfig, createPositionError, parseChat as default, detectContestantType, detectPropType, inferSportAndLeague, isFill, isHandicapLine, isHandicapML, isOrder, isPropOU, isPropYN, isSeries, isTotalPoints, isTotalPointsContestant, mapParseResultToSqlParameters, matchesIgnoreCase, parseChat, parseChatFill, parseChatOrder, parseFillSize, parseGameNumber, parseLine, parseOrderSize, parseOverUnder, parsePeriod, parsePrice, parseRotationNumber, parseTeam, parseTeams, validateGradingParameters, validatePropFormat };