import type { components } from "./generated/schema"; enum ApiErrorCode { BankDependentRefunds = "BANK_DEPENDENT_REFUNDS", BankIntentConflict = "BANK_INTENT_CONFLICT", BankNotFound = "BANK_NOT_FOUND", BankRefundLimit = "BANK_REFUND_LIMIT", BankVersionConflict = "BANK_VERSION_CONFLICT", BankWriteConflict = "BANK_WRITE_CONFLICT", BondTickerAmbiguous = "BOND_TICKER_AMBIGUOUS", InvalidOperationsCursor = "INVALID_OPERATIONS_CURSOR", InvalidTbankToken = "INVALID_TBANK_TOKEN", NotFound = "NOT_FOUND", StockTickerAmbiguous = "STOCK_TICKER_AMBIGUOUS", TbankNotConnected = "TBANK_NOT_CONNECTED", TbankUnavailable = "TBANK_UNAVAILABLE", Unauthorized = "UNAUTHORIZED", } /** Compile-time drift guard: collapses to `never` when any enum member is absent from the generated ProblemDetails contract, so every call site fails to build. */ type ContractApiErrorCode = Exclude< `${ApiErrorCode}`, components["schemas"]["ProblemDetailsDto"]["code"] > extends never ? ApiErrorCode : never; function apiErrorCode(error: unknown): string | undefined { return typeof error === "object" && error !== null && "code" in error ? String(error.code) : undefined; } // Incoming codes are an open wire string; unknown values retain their fallback. function isApiErrorCode( value: unknown, expected: ContractApiErrorCode, ): boolean { return value === expected; } // Confirmed loss of access to the brokerage data. UNAUTHORIZED is a session // failure with its own refresh/sign-out path, so it is deliberately excluded. function isBrokerageAccessLoss(code?: string): boolean { return [ ApiErrorCode.InvalidTbankToken, ApiErrorCode.NotFound, ApiErrorCode.TbankNotConnected, ].some(loss => isApiErrorCode(code, loss)); } export { ApiErrorCode, apiErrorCode, isApiErrorCode, isBrokerageAccessLoss };