Private/Get-DFCatalogLocalPackages.ps1
|
#Requires -Version 7.0 function Get-DFCatalogLocalPackages { <# .SYNOPSIS Aggregates every local catalog source (scoop index, winget index, cached web queries, and a live installed-package check) into one entry per package name with merged sources — never touches the network. #> [CmdletBinding()] [OutputType([PSCustomObject])] param() $cacheRoot = Get-DFCatalogCacheRoot if (-not $cacheRoot) { return } $aggregate = [ordered]@{} $add = { param($Name, $Source, $Description) if (-not $Name) { return } $key = ([string]$Name).ToLowerInvariant() if (-not $aggregate.Contains($key)) { $aggregate[$key] = @{ Name = [string]$Name Sources = [System.Collections.Generic.HashSet[string]]::new() Description = '' } } $null = $aggregate[$key].Sources.Add([string]$Source) if (-not $aggregate[$key].Description -and $Description) { $aggregate[$key].Description = [string]$Description } } $scoopIndex = Read-DFCatalogCacheFile -Path (Join-Path $cacheRoot 'scoop/index.json') -Ttl ([timespan]::MaxValue) foreach ($entry in @($scoopIndex.Data)) { & $add $entry.name 'scoop' $entry.description } $wingetDb = Join-Path $cacheRoot 'winget/index.db' if (Test-Path $wingetDb) { foreach ($row in @(Invoke-DFSqliteQuery -Database $wingetDb -Query 'SELECT id, name FROM packages')) { & $add ($row.name ? $row.name : $row.id) 'winget' $null } } foreach ($provider in $script:DFCatalogOrder) { $queriesDir = Join-Path $cacheRoot "$provider/queries" if (-not (Test-Path $queriesDir)) { continue } foreach ($file in Get-ChildItem $queriesDir -Filter '*.json' -File) { $cached = Read-DFCatalogCacheFile -Path $file.FullName -Ttl ([timespan]::MaxValue) foreach ($entry in @($cached.Data)) { & $add $entry.Name $provider $entry.Description } } } $installed = Get-DFCatalogInstalled foreach ($entry in @($installed.Items)) { & $add $entry.Name $entry.Source $null } foreach ($value in $aggregate.Values) { [pscustomobject]@{ Name = $value.Name Sources = @($value.Sources | Sort-Object) -join ',' Description = $value.Description } } } |