[READ-ONLY] a fast, modern browser for the npm registry
at main 422 lines 11 kB view raw
1/** 2 * npm Registry API Types 3 * Custom types for search and download APIs (not covered by @npm/types). 4 * 5 * @see https://github.com/npm/types 6 * @see https://github.com/npm/registry/blob/main/docs/REGISTRY-API.md 7 */ 8 9import type { 10 Packument as PackumentWithoutLicenseObjects, 11 PackumentVersion as PackumentVersionWithoutAttestations, 12 Contact, 13} from '@npm/types' 14import type { ReadmeResponse } from './readme' 15 16// Re-export official npm types for packument/manifest 17export type { Manifest, ManifestVersion, PackageJSON } from '@npm/types' 18 19type NpmTrustedPublisherEvidence = NpmSearchTrustedPublisher | NpmTrustedPublisher | true 20 21export interface PackumentVersion extends PackumentVersionWithoutAttestations { 22 _npmUser?: Contact & { trustedPublisher?: NpmTrustedPublisherEvidence } 23 dist: PackumentVersionWithoutAttestations['dist'] & { attestations?: NpmVersionAttestations } 24} 25 26export type Packument = Omit<PackumentWithoutLicenseObjects, 'license' | 'versions'> & { 27 // Fix for license field being incorrectly typed in @npm/types 28 // TODO: Remove this type override when @npm/types fixes the license field typing 29 license?: string | { type: string; url?: string } 30 versions: Record<string, PackumentVersion> 31} 32 33/** Install scripts info (preinstall, install, postinstall) */ 34export interface InstallScriptsInfo { 35 scripts: ('preinstall' | 'install' | 'postinstall')[] 36 content: Record<string, string> 37 npxDependencies: Record<string, string> 38} 39 40/** PackumentVersion with additional install scripts info */ 41export type SlimPackumentVersion = PackumentVersion & { 42 installScripts?: InstallScriptsInfo 43} 44 45export type PublishTrustLevel = 'none' | 'trustedPublisher' | 'provenance' 46 47export type SlimVersion = Pick<SlimPackumentVersion, 'version' | 'deprecated' | 'tags'> & { 48 hasProvenance?: boolean 49 trustLevel?: PublishTrustLevel 50} 51 52/** 53 * Slimmed down Packument for client-side use. 54 * Strips unnecessary fields to reduce payload size. 55 * - readme removed (fetched separately) 56 * - versions limited to dist-tag versions only 57 * - time limited to dist-tag versions 58 */ 59export interface SlimPackument { 60 '_id': string 61 '_rev'?: string 62 'name': string 63 'description'?: string 64 'dist-tags': { latest?: string } & Record<string, string> 65 /** 66 * Timestamps for package versions. 67 * 68 * **IMPORTANT**: Use `time[version]` to get the publish date of a specific version. 69 * 70 * **DO NOT use `time.modified`** - it can be updated by metadata changes (e.g., maintainer 71 * additions/removals) without any code being published, making it misleading for users 72 * trying to assess package maintenance activity. 73 * 74 * - `time[version]` - When that specific version was published (use this!) 75 * - `time.created` - When the package was first created 76 * - `time.modified` - Last metadata change (misleading - avoid using) 77 */ 78 'time': { modified?: string; created?: string } & Record<string, string> 79 'maintainers'?: NpmPerson[] 80 'author'?: NpmPerson 81 'license'?: string 82 'homepage'?: string 83 'keywords'?: string[] 84 'repository'?: { type?: string; url?: string; directory?: string } 85 'bugs'?: { url?: string; email?: string } 86 /** current version */ 87 'requestedVersion': SlimPackumentVersion | null 88 /** Only includes dist-tag versions (with installScripts info added per version) */ 89 'versions': Record<string, SlimVersion> 90 /** Lightweight security metadata for all versions */ 91 'securityVersions'?: PackageVersionInfo[] 92} 93 94/** 95 * Lightweight version info for the version list 96 */ 97export interface PackageVersionInfo { 98 version: string 99 time?: string 100 hasProvenance: boolean 101 trustLevel?: PublishTrustLevel 102 deprecated?: string 103} 104 105/** 106 * Person/contact type extracted from @npm/types Contact interface 107 * Used for maintainers, authors, publishers 108 */ 109export interface NpmPerson { 110 name?: string 111 email?: string 112 url?: string 113 username?: string 114} 115 116/** 117 * Search API response 118 * Returned by GET /-/v1/search 119 * Note: Not covered by @npm/types (see https://github.com/npm/types/issues/28) 120 */ 121export interface NpmSearchResponse { 122 isStale: boolean 123 objects: NpmSearchResult[] 124 total: number 125 time: string 126} 127 128export interface NpmSearchResult { 129 package: NpmSearchPackage 130 score: NpmSearchScore 131 searchScore: number 132 /** Download counts (weekly/monthly) */ 133 downloads?: { 134 weekly?: number 135 monthly?: number 136 } 137 /** Number of dependents */ 138 dependents?: string 139 /** Last updated timestamp (ISO 8601) */ 140 updated?: string 141 flags?: { 142 unstable?: boolean 143 insecure?: number 144 } 145} 146 147/** 148 * Trusted publisher info from search API 149 * Present when package was published via OIDC (e.g., GitHub Actions) 150 */ 151export interface NpmSearchTrustedPublisher { 152 /** OIDC provider identifier (e.g., "github", "gitlab") */ 153 id: string 154 /** OIDC config ID */ 155 oidcConfigId?: string 156} 157 158/** 159 * Publisher info with optional trusted publisher and actor details 160 */ 161export interface NpmSearchPublisher extends NpmPerson { 162 /** Trusted publisher info (present if published via OIDC) */ 163 trustedPublisher?: NpmSearchTrustedPublisher 164 /** Actor who triggered the publish (for trusted publishing) */ 165 actor?: { 166 name: string 167 type: 'user' | 'team' 168 email?: string 169 } 170} 171 172export interface NpmSearchPackage { 173 name: string 174 scope?: string 175 version: string 176 description?: string 177 keywords?: string[] 178 date: string 179 links: { 180 npm?: string 181 homepage?: string 182 repository?: string 183 bugs?: string 184 } 185 author?: NpmPerson 186 publisher?: NpmSearchPublisher 187 maintainers?: NpmPerson[] 188 license?: string 189} 190 191export interface NpmSearchScore { 192 final: number 193 detail: { 194 quality: number 195 popularity: number 196 maintenance: number 197 } 198} 199 200/** 201 * Attestations/provenance info on package version dist 202 * Present when package was published with provenance 203 * Note: Not covered by @npm/types 204 */ 205export interface NpmVersionAttestations { 206 /** URL to fetch full attestation details */ 207 url: string 208 /** Provenance info */ 209 provenance: { 210 /** SLSA predicate type URL */ 211 predicateType: string 212 } 213} 214 215/** 216 * Extended dist info that may include attestations 217 * The base PackumentVersion.dist doesn't include attestations 218 */ 219export interface NpmVersionDist { 220 shasum: string 221 tarball: string 222 integrity?: string 223 fileCount?: number 224 unpackedSize?: number 225 signatures?: Array<{ 226 keyid: string 227 sig: string 228 }> 229 /** Attestations/provenance (present if published with provenance) */ 230 attestations?: NpmVersionAttestations 231} 232 233/** 234 * Parsed provenance details for display (from attestation bundle SLSA predicate). 235 * Used by the provenance API and PackageProvenanceSection. 236 * @public 237 */ 238export interface ProvenanceDetails { 239 /** Provider ID (e.g. "github", "gitlab") */ 240 provider: string 241 /** Human-readable provider label (e.g. "GitHub Actions") */ 242 providerLabel: string 243 /** Link to build run summary (e.g. GitHub Actions run URL) */ 244 buildSummaryUrl?: string 245 /** Link to source commit in repository */ 246 sourceCommitUrl?: string 247 /** Source commit SHA (short or full) */ 248 sourceCommitSha?: string 249 /** Link to workflow/build config file in repo */ 250 buildFileUrl?: string 251 /** Workflow path (e.g. ".github/workflows/release.yml") */ 252 buildFilePath?: string 253 /** Link to transparency log entry (e.g. Sigstore search) */ 254 publicLedgerUrl?: string 255} 256 257/** 258 * Download counts API response 259 * From https://api.npmjs.org/downloads/ 260 * Note: Not covered by @npm/types 261 */ 262export interface NpmDownloadCount { 263 downloads: number 264 start: string 265 end: string 266 package: string 267} 268 269export interface NpmDownloadRange { 270 downloads: Array<{ 271 downloads: number 272 day: string 273 }> 274 start: string 275 end: string 276 package: string 277} 278 279/** 280 * Organization API types 281 * These require authentication 282 * Note: Not covered by @npm/types 283 */ 284export interface NpmOrgMember { 285 user: string 286 role: 'developer' | 'admin' | 'owner' 287} 288 289export interface NpmTeam { 290 name: string 291 description?: string 292 members?: string[] 293} 294 295export interface NpmPackageAccess { 296 permissions: 'read-only' | 'read-write' 297} 298 299/** 300 * Trusted Publishing types 301 * Note: Not covered by @npm/types 302 */ 303export interface NpmTrustedPublisher { 304 type: 'github-actions' | 'gitlab-ci' 305 // GitHub Actions specific 306 repository?: string 307 workflow?: string 308 environment?: string 309 // GitLab CI specific 310 namespace?: string 311 project?: string 312 ciConfigPath?: string 313} 314 315/** 316 * jsDelivr API Types 317 * Used for package file browsing 318 */ 319 320/** 321 * Response from jsDelivr package API (nested structure) 322 * GET https://data.jsdelivr.com/v1/packages/npm/{package}@{version} 323 */ 324export interface JsDelivrPackageResponse { 325 type: 'npm' 326 name: string 327 version: string 328 /** Default entry point file */ 329 default: string | null 330 /** Nested file tree */ 331 files: JsDelivrFileNode[] 332} 333 334/** 335 * A file or directory node from jsDelivr API 336 */ 337export interface JsDelivrFileNode { 338 type: 'file' | 'directory' 339 name: string 340 /** File hash (only for files) */ 341 hash?: string 342 /** File size in bytes (only for files) */ 343 size?: number 344 /** Child nodes (only for directories) */ 345 files?: JsDelivrFileNode[] 346} 347 348/** 349 * Tree node for package file browser 350 */ 351export interface PackageFileTree { 352 /** File or directory name */ 353 name: string 354 /** Full path from package root */ 355 path: string 356 /** Node type */ 357 type: 'file' | 'directory' 358 /** File size in bytes (only for files) */ 359 size?: number 360 /** Child nodes (only for directories) */ 361 children?: PackageFileTree[] 362} 363 364/** 365 * Response from file tree API 366 */ 367export interface PackageFileTreeResponse { 368 package: string 369 version: string 370 default?: string 371 tree: PackageFileTree[] 372} 373 374/** 375 * Response from file content API 376 */ 377export interface PackageFileContentResponse { 378 package: string 379 version: string 380 path: string 381 language: string 382 content: string 383 html: string 384 lines: number 385 markdownHtml?: ReadmeResponse 386} 387 388/** 389 * Minimal packument data needed for package cards 390 */ 391export interface MinimalPackument { 392 'name': string 393 'description'?: string 394 'keywords'?: string[] 395 // `dist-tags` can be missing in some later unpublished packages 396 'dist-tags'?: Record<string, string> 397 'time': Record<string, string> 398 'maintainers'?: NpmPerson[] 399} 400 401/** 402 * Lightweight package metadata returned by /api/registry/package-meta/. 403 * Contains only the fields needed for search result cards, extracted 404 * server-side from the full packument + downloads API. 405 */ 406export interface PackageMetaResponse { 407 name: string 408 version: string 409 description?: string 410 keywords?: string[] 411 license?: string 412 date: string 413 links: { 414 npm: string 415 homepage?: string 416 repository?: string 417 bugs?: string 418 } 419 author?: NpmPerson 420 maintainers?: NpmPerson[] 421 weeklyDownloads?: number 422}