Skip to content

Commit

Permalink
Support NPM packages which have links represented as arrays of strings (
Browse files Browse the repository at this point in the history
  • Loading branch information
cbrewster authored Dec 19, 2024
1 parent 9f8d08f commit 0f86a14
Showing 1 changed file with 47 additions and 55 deletions.
102 changes: 47 additions & 55 deletions internal/backends/nodejs/nodejs.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"net/url"
"os"
Expand Down Expand Up @@ -33,9 +32,9 @@ type npmSearchResults struct {
Version string `json:"version"`
Description string `json:"description"`
Links struct {
Homepage string `json:"homepage"`
Repository string `json:"repository"`
Bugs string `json:"bugs"`
Homepage packageLink `json:"homepage"`
Repository packageLink `json:"repository"`
Bugs packageLink `json:"bugs"`
} `json:"links"`
Author struct {
Username string `json:"username"`
Expand All @@ -45,6 +44,43 @@ type npmSearchResults struct {
} `json:"objects"`
}

type packageLink struct{ URL string }

var _ json.Unmarshaler = (*packageLink)(nil)

// UnmarshalJSON implements json.Unmarshaler.
//
// This supports link represented as a single string,
// list of strings (taking the first one), or an object
// with the field "url".
func (link *packageLink) UnmarshalJSON(data []byte) error {
var str string
if err := json.Unmarshal(data, &str); err == nil {
link.URL = str
return nil
}

var obj map[string]interface{}
if err := json.Unmarshal(data, &obj); err == nil {
if url, ok := obj["url"].(string); ok {
link.URL = url
}
return nil
}

var slice []string
if err := json.Unmarshal(data, &slice); err == nil {
if len(slice) == 0 {
link.URL = ""
return nil
}
link.URL = slice[0]
return nil
}

return errors.New("expected link to be a string, list of strings, or an object")
}

// npmInfoResult represents the data we get from the NPM API when
// doing a single package lookup.
//
Expand All @@ -63,33 +99,11 @@ type npmInfoResult struct {
Name string `json:"name"`
Versions map[string]interface{} `json:"versions"`
Author packageJsonPerson `json:"author"`
Bugs packageJsonBugs `json:"bugs"`
Bugs packageLink `json:"bugs"`
Description string `json:"description"`
Homepage string `json:"homepage"`
Homepage packageLink `json:"homepage"`
License string `json:"license"`
Repository packageJsonRepository `json:"repository"`
}

type packageJsonRepository struct {
URL string
}

func (repo *packageJsonRepository) UnmarshalJSON(data []byte) error {
var str string
if err := json.Unmarshal(data, &str); err == nil {
repo.URL = str
return nil
}

var obj map[string]interface{}
if err := json.Unmarshal(data, &obj); err == nil {
if url, ok := obj["url"].(string); ok {
repo.URL = url
}
return nil
}

return fmt.Errorf("expected repository in package.json to be a string or an object")
Repository packageLink `json:"repository"`
}

type packageJsonPerson struct {
Expand Down Expand Up @@ -152,28 +166,6 @@ func (person *packageJsonPerson) UnmarshalJSON(data []byte) error {
return errors.New("expected person in package.json to be a string or an object")
}

type packageJsonBugs struct {
URL string
}

func (bugs *packageJsonBugs) UnmarshalJSON(data []byte) error {
var str string
if err := json.Unmarshal(data, &str); err == nil {
bugs.URL = str
return nil
}

var obj map[string]interface{}
if err := json.Unmarshal(data, &obj); err == nil {
if url, ok := obj["url"].(string); ok {
bugs.URL = url
}
return nil
}

return errors.New("expected bugs in package.json to be a string or an object")
}

// packageJSON represents the relevant data in a package.json file.
type packageJSON struct {
Dependencies map[string]string `json:"dependencies"`
Expand Down Expand Up @@ -261,9 +253,9 @@ func nodejsSearch(query string) []api.PkgInfo {
Name: p.Name,
Description: p.Description,
Version: p.Version,
HomepageURL: p.Links.Homepage,
SourceCodeURL: p.Links.Repository,
BugTrackerURL: p.Links.Bugs,
HomepageURL: p.Links.Homepage.URL,
SourceCodeURL: p.Links.Repository.URL,
BugTrackerURL: p.Links.Bugs.URL,
Author: util.AuthorInfo{
Name: p.Author.Username,
Email: p.Author.Email,
Expand Down Expand Up @@ -329,7 +321,7 @@ func nodejsInfo(name api.PkgName) api.PkgInfo {
Name: npmInfo.Name,
Description: npmInfo.Description,
Version: lastVersionStr,
HomepageURL: npmInfo.Homepage,
HomepageURL: npmInfo.Homepage.URL,
SourceCodeURL: npmInfo.Repository.URL,
BugTrackerURL: npmInfo.Bugs.URL,
Author: util.AuthorInfo{
Expand Down

0 comments on commit 0f86a14

Please sign in to comment.