mirror of
https://github.com/go-gitea/gitea.git
synced 2026-10-01 20:59:45 +09:00
enhance(packages/npm): improve npm client compatibility (#39434)
Aligns the npm registry with what npm, pnpm and yarn expect: 1. Raise the publish body cap from https://github.com/go-gitea/gitea/pull/37890 to 256 MiB like npmjs, larger bodies get 413 2. Pick the tarball attachment by name, `npm publish --provenance` failed at random 3. Store and serve `libc`, so mismatched glibc/musl optional binaries are skipped 4. Treat root `*.gyp` files as an install script, like npm does 5. Always serve a `latest` dist-tag, yarn and pnpm fail without it 6. Take top-level metadata from `latest` and drop the per-version readme 7. Serve tarballs at the npmjs path `/<name>/-/<file>`, former URLs keep working 8. Add ETag revalidation for metadata, `npm ping` and `npm whoami` Tested with npm 12.1, pnpm 12.4, yarn 1.22 and yarn 4.18. --------- Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
@@ -104,6 +104,7 @@ func TestPackageNpm(t *testing.T) {
|
||||
},
|
||||
"cpu": ["x64", "arm64"],
|
||||
"os": ["linux", "darwin"],
|
||||
"libc": ["glibc"],
|
||||
"directories": {
|
||||
"doc": "./doc",
|
||||
"man": "./man"
|
||||
@@ -218,7 +219,7 @@ func TestPackageNpm(t *testing.T) {
|
||||
assert.Equal(t, packageBinPath, pmv.Bin[packageBinName])
|
||||
assert.Equal(t, integrity, pmv.Dist.Integrity)
|
||||
assert.Equal(t, sha1SumHex, pmv.Dist.Shasum)
|
||||
assert.Equal(t, fmt.Sprintf("%s%s/-/%s/%s", setting.AppURL, root[1:], packageVersion, filename), pmv.Dist.Tarball)
|
||||
assert.Equal(t, fmt.Sprintf("%sapi/packages/%s/npm/%s/-/%s", setting.AppURL, user.Name, packageName, filename), pmv.Dist.Tarball)
|
||||
assert.Equal(t, repoType, result.Repository.Type)
|
||||
assert.Equal(t, repoURL, result.Repository.URL)
|
||||
assert.Equal(t, map[string]string{"tea": "2.x", "soy-milk": "1.2"}, pmv.PeerDependencies)
|
||||
@@ -228,10 +229,24 @@ func TestPackageNpm(t *testing.T) {
|
||||
assert.Equal(t, map[string]string{"node": ">=22.7.0", "npm": ">=10.8.2"}, pmv.Engines)
|
||||
assert.Equal(t, []string{"x64", "arm64"}, pmv.CPU)
|
||||
assert.Equal(t, []string{"linux", "darwin"}, pmv.OS)
|
||||
assert.Equal(t, []string{"glibc"}, pmv.Libc)
|
||||
assert.Equal(t, map[string]string{"doc": "./doc", "man": "./man"}, pmv.Directories)
|
||||
assert.Equal(t, "https://example.com/fund", pmv.Funding)
|
||||
assert.Equal(t, map[string]string{"left-pad": "1.x"}, pmv.AcceptDependencies)
|
||||
assert.Empty(t, pmv.Deprecated)
|
||||
|
||||
req = NewRequest(t, "GET", root).AddTokenAuth(token).SetHeader("If-None-Match", resp.Header().Get("ETag"))
|
||||
MakeRequest(t, req, http.StatusNotModified)
|
||||
})
|
||||
|
||||
t.Run("PingWhoami", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
registry := fmt.Sprintf("/api/packages/%s/npm/-/", user.Name)
|
||||
MakeRequest(t, NewRequest(t, "GET", registry+"ping"), http.StatusOK)
|
||||
MakeRequest(t, NewRequest(t, "GET", registry+"whoami"), http.StatusUnauthorized)
|
||||
resp := MakeRequest(t, NewRequest(t, "GET", registry+"whoami").AddTokenAuth(token), http.StatusOK)
|
||||
assert.JSONEq(t, `{"username":"`+user.Name+`"}`, resp.Body.String())
|
||||
})
|
||||
|
||||
t.Run("PackageVersionMetadata", func(t *testing.T) {
|
||||
@@ -290,22 +305,6 @@ func TestPackageNpm(t *testing.T) {
|
||||
assert.Equal(t, packageVersion, result[packageTag2])
|
||||
})
|
||||
|
||||
t.Run("PackageMetadataDistTags", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
req := NewRequest(t, "GET", root).
|
||||
AddTokenAuth(token)
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
result := DecodeJSON(t, resp, &npm.PackageMetadata{})
|
||||
|
||||
assert.Len(t, result.DistTags, 2)
|
||||
assert.Contains(t, result.DistTags, packageTag)
|
||||
assert.Equal(t, packageVersion, result.DistTags[packageTag])
|
||||
assert.Contains(t, result.DistTags, packageTag2)
|
||||
assert.Equal(t, packageVersion, result.DistTags[packageTag2])
|
||||
})
|
||||
|
||||
t.Run("DeleteTag", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
@@ -319,6 +318,12 @@ func TestPackageNpm(t *testing.T) {
|
||||
test(t, http.StatusBadRequest, "1.0")
|
||||
test(t, http.StatusOK, "dummy")
|
||||
test(t, http.StatusOK, packageTag2)
|
||||
test(t, http.StatusOK, packageTag)
|
||||
|
||||
resp := MakeRequest(t, NewRequest(t, "GET", tagsRoot).AddTokenAuth(token), http.StatusOK)
|
||||
assert.Equal(t, map[string]string{packageTag: packageVersion}, DecodeJSON(t, resp, map[string]string{}))
|
||||
resp = MakeRequest(t, NewRequest(t, "GET", root+"/"+packageTag).AddTokenAuth(token), http.StatusOK)
|
||||
assert.Equal(t, packageVersion, DecodeJSON(t, resp, &npm.PackageMetadataVersion{}).Version)
|
||||
})
|
||||
|
||||
t.Run("Search", func(t *testing.T) {
|
||||
@@ -523,7 +528,7 @@ func TestPackageNpm(t *testing.T) {
|
||||
req := NewRequest(t, "DELETE", fmt.Sprintf("%s/-/%s/%s/-rev/dummy", root, packageVersion, filename))
|
||||
MakeRequest(t, req, http.StatusUnauthorized)
|
||||
|
||||
req = NewRequest(t, "DELETE", fmt.Sprintf("%s/-/%s/%s/-rev/dummy", root, packageVersion, filename)).
|
||||
req = NewRequest(t, "DELETE", fmt.Sprintf("%s/-/%s/-rev/dummy", root, filename)).
|
||||
AddTokenAuth(token)
|
||||
MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user