Skip to content

feat: resolve full dependency tree #12

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
from fastapi import FastAPI
from starlette.responses import Response

from npm_deps.models import NPMPackageVersion
from npm_deps.package_version import get_package_version
from npm_deps.package import get_package

app = FastAPI(title="NpmDepsService", version="1.0")

Expand All @@ -15,5 +14,5 @@ async def health() -> Response:


@app.get("/package/{name}/{version}", tags=["package"])
async def get_package(name: str, version: str) -> NPMPackageVersion:
return await get_package_version(name, version)
async def get_package_version(name: str, version: str): # type: ignore[no-untyped-def]
return await get_package(name, version)
11 changes: 10 additions & 1 deletion npm_deps/models.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
from pydantic import BaseModel
from pydantic.v1 import BaseModel


class VersionedPackage(BaseModel):
name: str
version: str
dependencies: list["VersionedPackage"] | None = None


class NPMPackageVersion(BaseModel):
Expand All @@ -10,3 +16,6 @@ class NPMPackageVersion(BaseModel):
class NPMPackage(BaseModel):
name: str
versions: dict[str, NPMPackageVersion]


VersionedPackage.update_forward_refs()
37 changes: 37 additions & 0 deletions npm_deps/package.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import requests
from nodesemver import min_satisfying

from npm_deps.models import VersionedPackage
from npm_deps.package_request import request_package


async def get_package(name: str, range: str | None = "*") -> VersionedPackage:
package_json = requests.get(f"https://registry.npmjs.org/{name}").json()
versions = list(package_json["versions"].keys())
version = min_satisfying(versions, range)
version_record = package_json["versions"][version]

package = VersionedPackage(
name=package_json["name"],
version=version_record["version"],
)
dependencies = version_record.get("dependencies", {})
package.dependencies = [
await get_package(name, version) for name, version in dependencies.items()
]
return package


async def get_package_version(name: str, range: str) -> VersionedPackage:
package_json = await request_package(name)
versions = list(package_json["versions"].keys())
version = min_satisfying(versions, range)
deps_list = []
for d in package_json["dependencies"]:
package = VersionedPackage(name=d, version=package_json["dependencies"][d])
deps_list.append(package)
return VersionedPackage(
name=name,
version=version,
dependencies=deps_list,
)
19 changes: 14 additions & 5 deletions tests/e2e/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,22 @@ def test_healthcheck():
assert response.status_code == HTTPStatus.NO_CONTENT


def test_get_package_by_name_and_version():
def test_get_package():
client = TestClient(app)
response = client.get("/package/react/16.3.0")
response = client.get("/package/minimatch/3.1.2")
assert response.status_code == HTTPStatus.OK
assert response.json().get("name") == "react"
assert response.json().get("version") == "16.3.0"
assert response.json().get("dependencies") is not None
assert response.json().get("name") == "minimatch"
assert response.json().get("version") == "3.1.2"
assert response.json().get("dependencies") == [
{
"name": "brace-expansion",
"version": "1.1.11",
"dependencies": [
{"name": "balanced-match", "version": "1.0.2", "dependencies": []},
{"name": "concat-map", "version": "0.0.1", "dependencies": []},
],
}
]


def test_get_package_by_name():
Expand Down
Loading