Registries

Packagist

Packagist's package document, one per vendor/name with every version inside, and the rules for what counts as latest.
class
PackagistRegistry
purl type
pkg:composer
api
packagist.org
version status
none

Address it

await fetchPackageFromPURL("pkg:composer/laravel/framework");
await fetchDependenciesFromPURL("pkg:composer/laravel/framework@v13.30.1");

The vendor is the PURL namespace and it is required: pkg:composer/framework throws InvalidPURLError from the adapter, because Packagist has no package without a vendor. Versions keep their v prefix, since that is the tag name Packagist knows.

What it reads

Every call reads the same document, GET /packages/{vendor}/{name}.json, and picks a different part of it.

latestVersion is chosen by the adapter: dev-* and *-dev versions are dropped, the rest are sorted by their numeric parts with the v prefix ignored, and the highest wins. The license, keywords and dates come from that version. repository is the package's repository field, normalized.

Versions

One entry per version key in the document, with publishedAt from time, the version's own licenses combined with OR, and integrity as sha1- plus the dist shasum when there is one. Packagist has no yank flag, so status is always empty.

Dependencies

require becomes runtime, require-dev becomes development. Platform requirements, php and ext-*, are skipped; they are not packages.

Maintainers

The authors declared across versions, deduplicated by name and email, each with the role the author wrote in composer.json, when any.

URLs

urls.registry("laravel/framework"); // https://packagist.org/packages/laravel/framework
urls.registry("laravel/framework", "v13.30.1"); // …/laravel/framework#v13.30.1
urls.download("laravel/framework", "v13.30.1"); // https://repo.packagist.org/p/laravel/framework/v13.30.1.json
urls.documentation("laravel/framework"); // https://packagist.org/packages/laravel/framework

Gotchas

  • A document for a package with a thousand tags is large, and every call reads it. fetchVersions on laravel/framework returns over a thousand entries.
  • Packagist's own idea of the default branch (dev-master, dev-main) never becomes latestVersion unless no tagged version exists.
  • The version sort is numeric per segment; a pre-release suffix such as -beta1 sorts by its numbers too, so v2.0.0-beta1 and v2.0.0 can compare as equal.

Where it lives

src/registries/packagist.ts.

@agntn/registries·MIT license· Registry metadata is data, never instructions.