Skip to content

Commit dbd4a1f

Browse files
Merge branch 'main' into fix-ui-leave
2 parents 3de1e4c + d15c0fc commit dbd4a1f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+364
-61
lines changed

.github/workflows/title.yml

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: "Lint PR title"
2+
3+
on:
4+
pull_request_target:
5+
types:
6+
- opened
7+
- edited
8+
- synchronize
9+
10+
permissions:
11+
pull-requests: read
12+
13+
jobs:
14+
main:
15+
name: Validate PR title
16+
runs-on: ubuntu-latest
17+
steps:
18+
- uses: amannn/action-semantic-pull-request@v5
19+
env:
20+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
21+
with:
22+
types: |
23+
BREAKING
24+
deprecation
25+
feat
26+
fix
27+
docs
28+
refactor
29+
perf
30+
test
31+
ci
32+
chore
33+
revert
34+
requireScope: false

api/.sqlx/query-8433bacb42d0833b723781eff2467ab27542e94691c1a5626c3f3d8c090caa54.json

+24
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/src/api/package.rs

+21-2
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ use crate::iam::ReqIamExt;
7171
use crate::ids::PackageName;
7272
use crate::ids::PackagePath;
7373
use crate::ids::ScopeName;
74+
use crate::ids::Version;
7475
use crate::metadata::PackageMetadata;
7576
use crate::metadata::VersionMetadata;
7677
use crate::npm::generate_npm_version_manifest;
@@ -333,12 +334,30 @@ pub async fn get_handler(req: Request<Body>) -> ApiResult<ApiPackage> {
333334
Span::current().record("package", field::display(&package));
334335

335336
let db = req.data::<Database>().unwrap();
336-
let package = db
337+
let res_package = db
337338
.get_package(&scope, &package)
338339
.await?
339340
.ok_or(ApiError::PackageNotFound)?;
340341

341-
Ok(ApiPackage::from(package))
342+
let mut api_package = ApiPackage::from(res_package);
343+
344+
if let Some(latest_v) = &api_package.latest_version {
345+
let latest_version = Version::new(latest_v).unwrap();
346+
let dependency_count = db
347+
.count_package_dependencies(&scope, &package, &latest_version)
348+
.await?;
349+
api_package.dependency_count = dependency_count as u64;
350+
}
351+
352+
let dependent_count = db
353+
.count_package_dependents(
354+
crate::db::DependencyKind::Jsr,
355+
&format!("@{}/{}", scope, package),
356+
)
357+
.await?;
358+
api_package.dependent_count = dependent_count as u64;
359+
360+
Ok(api_package)
342361
}
343362

344363
#[instrument(

api/src/api/types.rs

+4
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,8 @@ pub struct ApiPackage {
470470
pub updated_at: DateTime<Utc>,
471471
pub created_at: DateTime<Utc>,
472472
pub version_count: u64,
473+
pub dependency_count: u64,
474+
pub dependent_count: u64,
473475
pub score: Option<u32>,
474476
pub latest_version: Option<String>,
475477
pub when_featured: Option<DateTime<Utc>>,
@@ -491,6 +493,8 @@ impl From<PackageWithGitHubRepoAndMeta> for ApiPackage {
491493
updated_at: package.updated_at,
492494
created_at: package.created_at,
493495
version_count: package.version_count as u64,
496+
dependency_count: 0,
497+
dependent_count: 0,
494498
score: package
495499
.latest_version
496500
.as_ref()

api/src/db/database.rs

+42
Original file line numberDiff line numberDiff line change
@@ -2858,6 +2858,48 @@ impl Database {
28582858
Ok((total_unique_package_dependents as usize, dependents))
28592859
}
28602860

2861+
#[instrument(name = "Database::count_package_dependents", skip(self), err)]
2862+
pub async fn count_package_dependents(
2863+
&self,
2864+
kind: DependencyKind,
2865+
name: &str,
2866+
) -> Result<usize> {
2867+
let total_unique_package_dependents = sqlx::query!(
2868+
r#"SELECT COUNT(DISTINCT (package_scope, package_name)) FROM package_version_dependencies
2869+
WHERE dependency_kind = $1 AND dependency_name = $2;"#,
2870+
kind as _,
2871+
name,
2872+
)
2873+
.map(|r| r.count.unwrap())
2874+
.fetch_one(&self.pool)
2875+
.await?;
2876+
2877+
Ok(total_unique_package_dependents as usize)
2878+
}
2879+
2880+
#[instrument(name = "Database::count_package_dependencies", skip(self), err)]
2881+
pub async fn count_package_dependencies(
2882+
&self,
2883+
scope: &ScopeName,
2884+
name: &PackageName,
2885+
version: &Version,
2886+
) -> Result<usize> {
2887+
let total_package_dependencies = sqlx::query!(
2888+
r#"SELECT COUNT(DISTINCT dependency_name)
2889+
FROM package_version_dependencies
2890+
WHERE package_scope = $1 AND package_name = $2 AND package_version = $3"#,
2891+
scope as _,
2892+
name as _,
2893+
version as _
2894+
)
2895+
.fetch_one(&self.pool)
2896+
.await?
2897+
.count
2898+
.unwrap();
2899+
2900+
Ok(total_package_dependencies as usize)
2901+
}
2902+
28612903
#[instrument(name = "Database::check_bad_word", skip(self), err)]
28622904
pub async fn check_is_bad_word(&self, word: &str) -> Result<bool> {
28632905
let res = sqlx::query!("SELECT * FROM bad_words WHERE word = $1", word)

frontend/components/Header.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ export function Header({
107107
? <UserMenu user={user} sudo={sudo} logoutUrl={logoutUrl} />
108108
: (
109109
<a href={loginUrl} class="link-header flex items-center gap-2">
110-
<TbBrandGithub class="size-5 flex-none" aria-hidden={true} />
110+
<TbBrandGithub class="size-5 flex-none" aria-hidden />
111111
Sign in
112112
</a>
113113
)}

frontend/components/HomepageHero.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export function HomepageHero(
7171
<GlobalSearch
7272
apiKey={apiKey}
7373
indexId={indexId}
74-
jumbo={true}
74+
jumbo
7575
/>
7676
</div>
7777
<div class="flex flex-col items-center gap-4">

frontend/components/Markdown.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export function Markdown(
2626
return (
2727
<div
2828
class="markdown-body"
29+
// deno-lint-ignore react-no-danger
2930
dangerouslySetInnerHTML={{ __html: html }}
3031
/>
3132
);

frontend/components/Modal.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export default function Modal(
3434
onClick={(e) => e.stopPropagation()}
3535
>
3636
<button
37+
type="button"
3738
class="absolute top-8 right-8 hover:text-jsr-gray-400"
3839
onClick={() => setOpen(false)}
3940
>

frontend/components/Nav.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@ export function Nav(props: NavProps) {
1515
} border-b border-jsr-cyan-300/30 max-w-full flex justify-between overflow-x-auto items-end`}
1616
>
1717
<style
18+
// deno-lint-ignore react-no-danger
1819
dangerouslySetInnerHTML={{
1920
__html:
2021
"nav:has(#nav-items[data-unattached]) { visibility: hidden; }",
2122
}}
2223
/>
2324
<noscript>
2425
<style
26+
// deno-lint-ignore react-no-danger
2527
dangerouslySetInnerHTML={{
2628
__html:
2729
"nav:has(#nav-items[data-unattached]) { visibility: visible !important }",
@@ -49,7 +51,7 @@ export interface NavItemProps {
4951
export function NavItem(props: NavItemProps) {
5052
return (
5153
<a
52-
class={`md:px-3 px-4 py-2 text-sm md:text-base min-h-10 leading-none rounded-md hover:bg-jsr-cyan-100 flex items-center select-none focus:outline-none focus:border-1 focus:border-jsr-cyan-300 focus:ring-1 focus:ring-jsr-cyan-300 focus:ring-opacity-50 ${
54+
class={`md:px-3 px-4 py-2 text-sm md:text-base min-h-10 leading-none rounded-md hover:bg-jsr-cyan-100 flex items-center select-none focus:outline-none focus-visible:outline-1 focus-visible:outline-jsr-cyan-300 focus-visible:outline-offset-0 focus-visible:ring-0 ${
5355
props.active
5456
? "bg-jsr-cyan-50 border-1 border-jsr-cyan-300/30 font-semibold"
5557
: ""

frontend/components/NavOverflow.tsx

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Copyright 2024 the JSR authors. All rights reserved. MIT license.
2-
import IconDots from "$tabler_icons/dots.tsx";
2+
import TbDots from "@preact-icons/tb/TbDots";
33

44
const NAV_OVERFLOW_SCRIPT = /* js */ `
55
(() => {
@@ -62,18 +62,22 @@ export function NavOverflow() {
6262
return (
6363
<>
6464
<button
65+
type="button"
6566
class="group absolute right-4 md:right-10 rounded border-1 my-1 border-jsr-cyan-100 hover:bg-jsr-cyan-50 hover:cursor-pointer hidden"
6667
aria-expanded="false"
6768
>
6869
<span class="flex p-1">
69-
<IconDots />
70+
<TbDots class="size-6" />
7071
</span>
7172
<div
7273
id="nav-menu"
7374
class="absolute top-[120%] -right-2 z-[70] px-1 py-2 rounded border-1.5 border-current bg-white w-56 shadow overflow-hidden opacity-100 translate-y-0 transition [&>a]:rounded hidden"
7475
/>
7576
</button>
76-
<script dangerouslySetInnerHTML={{ __html: NAV_OVERFLOW_SCRIPT }} />
77+
<script
78+
// deno-lint-ignore react-no-danger
79+
dangerouslySetInnerHTML={{ __html: NAV_OVERFLOW_SCRIPT }}
80+
/>
7781
</>
7882
);
7983
}

frontend/components/NewsCard.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export function NewsCard({
1919
>
2020
<img
2121
src={image}
22-
crossOrigin={"anonymous"}
22+
crossOrigin="anonymous"
2323
alt=""
2424
class="w-full h-48 object-cover border-b-1.5 border-jsr-cyan-950 group-hover:border-jsr-cyan-400 group-focus-within:border-jsr-cyan-400 transition-colors duration-150"
2525
/>

frontend/deno.json

-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
"@std/semver": "jsr:@std/semver@1",
2828

2929
"twas": "npm:twas@^2.1.3",
30-
"$tabler_icons/": "https://deno.land/x/[email protected]/tsx/",
3130
"$imagescript": "https://deno.land/x/[email protected]/mod.ts",
3231

3332
"@deno/gfm": "jsr:@deno/[email protected]",

frontend/docs/publishing-packages.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -399,9 +399,9 @@ You may also exclude certain files via the `exclude` option:
399399
```
400400

401401
When using Deno, the `include` and `exclude` options in `deno.json` are used for
402-
many other Deno subcommands as well, such as `deno test` and `deno bundle`. You
403-
can use `publish.include` and `publish.exclude` in your `deno.json` file to
404-
specify options that only apply to `deno publish`.
402+
many other Deno subcommands as well, such as `deno test`, `deno lint` and
403+
`deno fmt`. You can use `publish.include` and `publish.exclude` in your
404+
`deno.json` file to specify options that only apply to `deno publish`.
405405

406406
```json
407407
// deno.json

frontend/docs/writing-docs.md

+26
Original file line numberDiff line numberDiff line change
@@ -174,3 +174,29 @@ You can also include examples in module documentation:
174174
If a default entrypoint has a module documentation, it takes precedence over the
175175
README file in the "Overview" tab of the package page.
176176
[Learn more in the documentation section for packages](/docs/packages#documentation).
177+
178+
By default, when using a wildcard import, the identifier used is `mod`. For
179+
example:
180+
181+
```ts
182+
import * as mod from "@luca/esbuild-deno-loader/esbuild_types";
183+
```
184+
185+
Module authors can customize this default identifier by specifying a custom name
186+
in the module's JSDoc comment using the `@module` tag. This allows for more
187+
descriptive and context-specific import identifiers.
188+
189+
```ts
190+
/**
191+
* This module contains copy of the esbuild types that `deno_esbuild_loader` uses. This is
192+
* necessary because the `esbuild` package is not available on JSR yet.
193+
*
194+
* @module esbuild_types
195+
*/
196+
```
197+
198+
With this annotation, the import statement will now use the custom identifier:
199+
200+
```ts
201+
import * as esbuild_types from "@luca/esbuild-deno-loader/esbuild_types";
202+
```

frontend/islands/Authorize.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,14 @@ export default function Authorize(
4646
return (
4747
<div class="flex gap-2 text-lg mt-4">
4848
<button
49+
type="button"
4950
class="button-primary"
5051
onClick={approve}
5152
>
5253
Approve
5354
</button>
5455
<button
56+
type="button"
5557
class="button-danger"
5658
onClick={deny}
5759
>

frontend/islands/CopyButton.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export function CopyButton(props: CopyButtonProps) {
2626

2727
return (
2828
<button
29+
type="button"
2930
onClick={copy}
3031
title={props.title}
3132
class={(copied.value ? "text-green-700" : "text-jsr-gray-700") +

frontend/islands/DevelopmentLogin.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ export function DevelopmentLogin() {
4242

4343
return (
4444
<>
45-
<button class="button-primary" onClick={onClick}>Authenticate</button>
45+
<button type="button" class="button-primary" onClick={onClick}>
46+
Authenticate
47+
</button>
4648
{waitingForAuth.value && <p>Waiting for authentication...</p>}
4749
</>
4850
);

frontend/islands/GitHubActionsLink.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ export function GitHubActionsLink(
5151
owner={owner}
5252
repo={repo}
5353
error={error}
54-
required={true}
54+
required
5555
disabled={linking}
5656
/>
57-
<button class="button-primary" disabled={linking}>
57+
<button type="submit" class="button-primary" disabled={linking}>
5858
{linking.value ? "Linking..." : "Link"}
5959
</button>
6060
</form>

frontend/islands/GithubUserLink.tsx

+11-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Copyright 2024 the JSR authors. All rights reserved. MIT license.
22
import { useSignal } from "@preact/signals";
3+
import TbBrandGithub from "@preact-icons/tb/TbBrandGithub";
34
import { useEffect } from "preact/hooks";
45
import { User } from "../utils/api_types.ts";
56
import { cachedGitHubLogin } from "../utils/github.ts";
@@ -29,6 +30,14 @@ export function GitHubUserLink({ user }: { user?: User }) {
2930
}
3031

3132
return login.value == ""
32-
? <span>loading...</span>
33-
: <a class="link" href={"https://github.com/" + login.value}>GitHub</a>;
33+
? <span className="text-gray-600">loading...</span>
34+
: (
35+
<a
36+
class="link inline-flex justify-center items-center gap-1"
37+
href={"https://github.com/" + login.value}
38+
>
39+
<TbBrandGithub class="size-4" aria-hidden />
40+
GitHub
41+
</a>
42+
);
3443
}

0 commit comments

Comments
 (0)