(
barService: BarService,
input: { query?: string; barId?: string; asset?: AssetArg },
)
| 38 | } |
| 39 | |
| 40 | export async function resolveBarSource( |
| 41 | barService: BarService, |
| 42 | input: { query?: string; barId?: string; asset?: AssetArg }, |
| 43 | ): Promise<ResolveResult | { error: string }> { |
| 44 | if (input.barId) { |
| 45 | return { ref: { barId: input.barId, ...(input.asset ? { assetClass: input.asset } : {}) } } |
| 46 | } |
| 47 | if (!input.query) return { error: 'Pass either query (a symbol) or barId.' } |
| 48 | |
| 49 | const candidates = await barService.searchBarSources(input.query, { limit: 12 }) |
| 50 | if (candidates.length === 0) { |
| 51 | return { error: `No bar source found for "${input.query}". Try searchBars to see candidates, or pass a barId.` } |
| 52 | } |
| 53 | const best = [...candidates].sort((a, b) => { |
| 54 | const da = Number(isDerivative(a.barId)) |
| 55 | const db = Number(isDerivative(b.barId)) |
| 56 | if (da !== db) return da - db // non-derivative (the real contract) first |
| 57 | const fa = a.barCapability ? FRESHNESS_RANK[a.barCapability] : 5 |
| 58 | const fb = b.barCapability ? FRESHNESS_RANK[b.barCapability] : 5 |
| 59 | return fa - fb // then freshest |
| 60 | })[0] |
| 61 | |
| 62 | const assetClass = best.assetClass !== 'unknown' ? (best.assetClass as AssetClass) : undefined |
| 63 | return { |
| 64 | ref: { barId: best.barId, ...(assetClass ? { assetClass: assetClass as AssetArg } : {}) }, |
| 65 | pickedFrom: `${best.barId} (${best.barCapability ?? 'unknown'})`, |
| 66 | } |
| 67 | } |
no test coverage detected