Skip to content

Commit 15c133f

Browse files
authored
Fix Composer minified metadata expansion and namespaced package routing (#63)
* Fix Composer minified metadata expansion and namespaced package routing Packagist serves metadata in a minified format where only the first version entry has all fields and subsequent entries inherit from the previous one. The proxy was passing this through without expanding it, which meant cooldown filtering could break the inheritance chain (losing fields like `name`) and `~dev` sentinel markers were silently dropped. The proxy now expands the minified format before filtering and rewriting, ensuring every version entry is self-contained. Web UI and API routes used single-segment chi URL params for package names, which broke for Composer's `vendor/name` format. `/package/composer/monolog/monolog` would match the version show route instead of the package show route. All `/package/` and related API routes now use wildcard paths with a `resolvePackageName` helper that tries increasingly longer path prefixes as package names via DB lookup, correctly handling namespaced packages across all endpoints (show, version, browse, compare, vulns). Fixes #61, fixes #62 * Add namespaced package routing tests for all affected ecosystems Verifies the wildcard routing handles slashes in package names for npm (@babel/core), Go modules (github.com/stretchr/testify), OCI images (library/nginx), Conda (conda-forge/numpy), and Conan (zlib/1.2.13@demo/stable). * Regenerate swagger docs after route refactor The swagger annotations for the old per-endpoint handlers were removed during the wildcard routing refactor. Regenerate to match current state.
1 parent e45706d commit 15c133f

11 files changed

Lines changed: 775 additions & 820 deletions

File tree

docs/swagger/docs.go

Lines changed: 0 additions & 312 deletions
Original file line numberDiff line numberDiff line change
@@ -297,115 +297,6 @@ const docTemplate = `{
297297
}
298298
}
299299
},
300-
"/api/package/{ecosystem}/{name}": {
301-
"get": {
302-
"description": "Returns enriched package metadata. URL-encode scoped names (e.g. @scope/name -\u003e %40scope%2Fname).",
303-
"produces": [
304-
"application/json"
305-
],
306-
"tags": [
307-
"api"
308-
],
309-
"summary": "Get package metadata",
310-
"parameters": [
311-
{
312-
"type": "string",
313-
"description": "Ecosystem",
314-
"name": "ecosystem",
315-
"in": "path",
316-
"required": true
317-
},
318-
{
319-
"type": "string",
320-
"description": "Package name",
321-
"name": "name",
322-
"in": "path",
323-
"required": true
324-
}
325-
],
326-
"responses": {
327-
"200": {
328-
"description": "OK",
329-
"schema": {
330-
"$ref": "#/definitions/server.PackageResponse"
331-
}
332-
},
333-
"400": {
334-
"description": "Bad Request",
335-
"schema": {
336-
"type": "string"
337-
}
338-
},
339-
"404": {
340-
"description": "Not Found",
341-
"schema": {
342-
"type": "string"
343-
}
344-
},
345-
"500": {
346-
"description": "Internal Server Error",
347-
"schema": {
348-
"type": "string"
349-
}
350-
}
351-
}
352-
}
353-
},
354-
"/api/package/{ecosystem}/{name}/{version}": {
355-
"get": {
356-
"description": "Returns enriched package+version metadata and vulnerability data.",
357-
"produces": [
358-
"application/json"
359-
],
360-
"tags": [
361-
"api"
362-
],
363-
"summary": "Get version metadata and vulnerabilities",
364-
"parameters": [
365-
{
366-
"type": "string",
367-
"description": "Ecosystem",
368-
"name": "ecosystem",
369-
"in": "path",
370-
"required": true
371-
},
372-
{
373-
"type": "string",
374-
"description": "Package name",
375-
"name": "name",
376-
"in": "path",
377-
"required": true
378-
},
379-
{
380-
"type": "string",
381-
"description": "Version",
382-
"name": "version",
383-
"in": "path",
384-
"required": true
385-
}
386-
],
387-
"responses": {
388-
"200": {
389-
"description": "OK",
390-
"schema": {
391-
"$ref": "#/definitions/server.EnrichmentResponse"
392-
}
393-
},
394-
"400": {
395-
"description": "Bad Request",
396-
"schema": {
397-
"type": "string"
398-
}
399-
},
400-
"500": {
401-
"description": "Internal Server Error",
402-
"schema": {
403-
"type": "string"
404-
}
405-
}
406-
}
407-
}
408-
},
409300
"/api/packages": {
410301
"get": {
411302
"produces": [
@@ -505,108 +396,6 @@ const docTemplate = `{
505396
}
506397
}
507398
},
508-
"/api/vulns/{ecosystem}/{name}": {
509-
"get": {
510-
"description": "Returns vulnerabilities for a package across versions, or for a specific version if provided.",
511-
"produces": [
512-
"application/json"
513-
],
514-
"tags": [
515-
"api"
516-
],
517-
"summary": "Get vulnerabilities for a package or version",
518-
"parameters": [
519-
{
520-
"type": "string",
521-
"description": "Ecosystem",
522-
"name": "ecosystem",
523-
"in": "path",
524-
"required": true
525-
},
526-
{
527-
"type": "string",
528-
"description": "Package name",
529-
"name": "name",
530-
"in": "path",
531-
"required": true
532-
}
533-
],
534-
"responses": {
535-
"200": {
536-
"description": "OK",
537-
"schema": {
538-
"$ref": "#/definitions/server.VulnsResponse"
539-
}
540-
},
541-
"400": {
542-
"description": "Bad Request",
543-
"schema": {
544-
"type": "string"
545-
}
546-
},
547-
"500": {
548-
"description": "Internal Server Error",
549-
"schema": {
550-
"type": "string"
551-
}
552-
}
553-
}
554-
}
555-
},
556-
"/api/vulns/{ecosystem}/{name}/{version}": {
557-
"get": {
558-
"description": "Returns vulnerabilities for a package across versions, or for a specific version if provided.",
559-
"produces": [
560-
"application/json"
561-
],
562-
"tags": [
563-
"api"
564-
],
565-
"summary": "Get vulnerabilities for a package or version",
566-
"parameters": [
567-
{
568-
"type": "string",
569-
"description": "Ecosystem",
570-
"name": "ecosystem",
571-
"in": "path",
572-
"required": true
573-
},
574-
{
575-
"type": "string",
576-
"description": "Package name",
577-
"name": "name",
578-
"in": "path",
579-
"required": true
580-
},
581-
{
582-
"type": "string",
583-
"description": "Version",
584-
"name": "version",
585-
"in": "path"
586-
}
587-
],
588-
"responses": {
589-
"200": {
590-
"description": "OK",
591-
"schema": {
592-
"$ref": "#/definitions/server.VulnsResponse"
593-
}
594-
},
595-
"400": {
596-
"description": "Bad Request",
597-
"schema": {
598-
"type": "string"
599-
}
600-
},
601-
"500": {
602-
"description": "Internal Server Error",
603-
"schema": {
604-
"type": "string"
605-
}
606-
}
607-
}
608-
}
609-
},
610399
"/health": {
611400
"get": {
612401
"produces": [
@@ -715,29 +504,6 @@ const docTemplate = `{
715504
}
716505
}
717506
},
718-
"server.EnrichmentResponse": {
719-
"type": "object",
720-
"properties": {
721-
"is_outdated": {
722-
"type": "boolean"
723-
},
724-
"license_category": {
725-
"type": "string"
726-
},
727-
"package": {
728-
"$ref": "#/definitions/server.PackageResponse"
729-
},
730-
"version": {
731-
"$ref": "#/definitions/server.VersionResponse"
732-
},
733-
"vulnerabilities": {
734-
"type": "array",
735-
"items": {
736-
"$ref": "#/definitions/server.VulnResponse"
737-
}
738-
}
739-
}
740-
},
741507
"server.OutdatedPackage": {
742508
"type": "object",
743509
"properties": {
@@ -949,84 +715,6 @@ const docTemplate = `{
949715
"type": "integer"
950716
}
951717
}
952-
},
953-
"server.VersionResponse": {
954-
"type": "object",
955-
"properties": {
956-
"ecosystem": {
957-
"type": "string"
958-
},
959-
"integrity": {
960-
"type": "string"
961-
},
962-
"is_outdated": {
963-
"type": "boolean"
964-
},
965-
"license": {
966-
"type": "string"
967-
},
968-
"name": {
969-
"type": "string"
970-
},
971-
"published_at": {
972-
"type": "string"
973-
},
974-
"version": {
975-
"type": "string"
976-
},
977-
"yanked": {
978-
"type": "boolean"
979-
}
980-
}
981-
},
982-
"server.VulnResponse": {
983-
"type": "object",
984-
"properties": {
985-
"cvss_score": {
986-
"type": "number"
987-
},
988-
"fixed_version": {
989-
"type": "string"
990-
},
991-
"id": {
992-
"type": "string"
993-
},
994-
"references": {
995-
"type": "array",
996-
"items": {
997-
"type": "string"
998-
}
999-
},
1000-
"severity": {
1001-
"type": "string"
1002-
},
1003-
"summary": {
1004-
"type": "string"
1005-
}
1006-
}
1007-
},
1008-
"server.VulnsResponse": {
1009-
"type": "object",
1010-
"properties": {
1011-
"count": {
1012-
"type": "integer"
1013-
},
1014-
"ecosystem": {
1015-
"type": "string"
1016-
},
1017-
"name": {
1018-
"type": "string"
1019-
},
1020-
"version": {
1021-
"type": "string"
1022-
},
1023-
"vulnerabilities": {
1024-
"type": "array",
1025-
"items": {
1026-
"$ref": "#/definitions/server.VulnResponse"
1027-
}
1028-
}
1029-
}
1030718
}
1031719
}
1032720
}`

0 commit comments

Comments
 (0)