(
languageId: LanguageKey,
fields?: string[],
)
| 243 | getLibrariesAsArray(languageId: LanguageKey, fields: string[] | undefined): Partial<LibraryArrayEntry>[]; |
| 244 | getLibrariesAsArray(languageId: LanguageKey): LibraryArrayEntry[]; |
| 245 | getLibrariesAsArray( |
| 246 | languageId: LanguageKey, |
| 247 | fields?: string[], |
| 248 | ): LibraryArrayEntry[] | Partial<LibraryArrayEntry>[] { |
| 249 | const libsForLanguageObj = unwrap(this.options).options.libs[languageId]; |
| 250 | if (!libsForLanguageObj) return []; |
| 251 | |
| 252 | // Field filtering supports dotted paths for nested version fields |
| 253 | // (e.g. `versions.id,versions.version`). Bare `versions` includes the |
| 254 | // full version objects. Omitting `fields` returns the legacy full shape. |
| 255 | const VERSION_PREFIX = 'versions.'; |
| 256 | let topLevelFields: string[] | undefined; |
| 257 | let versionFields: string[] | undefined; |
| 258 | if (fields && fields.length > 0) { |
| 259 | topLevelFields = []; |
| 260 | versionFields = []; |
| 261 | let allVersionFields = false; |
| 262 | for (const f of fields) { |
| 263 | if (f.startsWith(VERSION_PREFIX)) { |
| 264 | versionFields.push(f.slice(VERSION_PREFIX.length)); |
| 265 | } else if (f === 'versions') { |
| 266 | allVersionFields = true; |
| 267 | topLevelFields.push(f); |
| 268 | } else { |
| 269 | topLevelFields.push(f); |
| 270 | } |
| 271 | } |
| 272 | if (allVersionFields) { |
| 273 | versionFields = undefined; |
| 274 | } else if (versionFields.length > 0 && !topLevelFields.includes('versions')) { |
| 275 | topLevelFields.push('versions'); |
| 276 | } |
| 277 | } |
| 278 | |
| 279 | // Build the full, concretely-typed shape first so callers that omit |
| 280 | // `fields` (e.g. the MCP tools) get the legacy non-partial type back. |
| 281 | const fullList: LibraryArrayEntry[] = Object.keys(libsForLanguageObj).map(key => { |
| 282 | const library = libsForLanguageObj[key]; |
| 283 | const versions = Object.keys(library.versions).map(versionKey => ({ |
| 284 | ...library.versions[versionKey], |
| 285 | id: versionKey, |
| 286 | })); |
| 287 | return { |
| 288 | id: key, |
| 289 | name: library.name, |
| 290 | description: library.description, |
| 291 | url: library.url, |
| 292 | versions, |
| 293 | }; |
| 294 | }); |
| 295 | |
| 296 | if (!topLevelFields && !versionFields) return fullList; |
| 297 | |
| 298 | return fullList.map(fullLib => { |
| 299 | const lib = versionFields |
| 300 | ? {...fullLib, versions: fullLib.versions.map(v => _.pick(v, versionFields!))} |
| 301 | : fullLib; |
| 302 | return topLevelFields ? _.pick(lib, topLevelFields) : lib; |
no test coverage detected