readScopeListing(body: unknown): ScopePackage[] | undefined
Reads a package listing out of a parsed JSR scope-packages response.
This is the whole of the response-shape knowledge, kept pure so the network path and the cache file can share it and so it can be tested without either. An entry without a usable name is dropped, a missing description becomes the empty string, and the CLI's own package is never a member. The result is sorted by name, because the order the API returns is not part of its contract.
An entry with no latestVersion is dropped, because it is a reserved
name and not a package: JSR answers the scope listing with every name that
has been claimed, published or not. @binstruct/bencode is the standing
example — latestVersion: null, versionCount: 0,
https://jsr.io/@binstruct/bencode/meta.json 404 — and offering it at
level 0 would put a name on the screen that binstruct bencode cannot load,
which is the one thing a suggestion list must not do.
The cache file is written in this same shape, so a hand-edited or truncated cache is rejected by the same rules as a bad response, and a cached listing carries the versions that got its entries past this filter.
A listing is read, sorted, and stripped of the CLI itself
A listing is read, sorted, and stripped of the CLI itself
import { assertEquals } from "@std/assert"; import { readScopeListing } from "./scope.ts"; const packages = readScopeListing({ items: [ { name: "png", description: "PNG image format.", latestVersion: "0.4.0" }, { name: "cli", description: "The CLI.", latestVersion: "0.2.0" }, { name: "arp", latestVersion: "0.3.0" }, ], }); assertEquals(packages, [ { name: "arp", description: "", latestVersion: "0.3.0" }, { name: "png", description: "PNG image format.", latestVersion: "0.4.0" }, ]);
A reserved name with nothing published behind it is not offered
A reserved name with nothing published behind it is not offered
import { assertEquals } from "@std/assert"; import { readScopeListing } from "./scope.ts"; assertEquals( readScopeListing({ items: [ { name: "bencode", description: "Bencode.", latestVersion: null }, { name: "tar", description: "Tar.", latestVersion: "0.1.0" }, ], }), [{ name: "tar", description: "Tar.", latestVersion: "0.1.0" }], );
A body that is not a listing is rejected rather than read as empty
A body that is not a listing is rejected rather than read as empty
import { assertEquals } from "@std/assert"; import { readScopeListing } from "./scope.ts"; assertEquals(readScopeListing({ error: "not found" }), undefined); assertEquals(readScopeListing("<!doctype html>"), undefined); assertEquals(readScopeListing({ items: [] }), []);
ScopePackage[] | undefined
The packages, or undefined when the body is not a listing at all