@tscircuit/fake-snippets 0.0.105 → 0.0.107
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +92 -0
- package/api/generated-index.js +3 -4
- package/bun-tests/fake-snippets-api/routes/package_builds/get.test.ts +294 -0
- package/bun-tests/fake-snippets-api/routes/package_builds/list.test.ts +304 -0
- package/dist/bundle.js +698 -335
- package/dist/index.d.ts +147 -4
- package/dist/index.js +195 -7
- package/dist/schema.d.ts +206 -1
- package/dist/schema.js +31 -2
- package/fake-snippets-api/lib/db/db-client.ts +60 -3
- package/fake-snippets-api/lib/db/schema.ts +31 -0
- package/fake-snippets-api/lib/db/seed.ts +139 -2
- package/fake-snippets-api/lib/public-mapping/public-map-package-build.ts +41 -0
- package/fake-snippets-api/routes/api/package_builds/get.ts +70 -0
- package/fake-snippets-api/routes/api/package_builds/list.ts +97 -0
- package/package.json +3 -2
- package/src/App.tsx +21 -5
- package/src/components/PackageBreadcrumb.tsx +111 -0
- package/src/components/ViewPackagePage/components/sidebar-releases-section.tsx +22 -11
- package/src/components/preview/BuildsList.tsx +196 -211
- package/src/components/preview/ConnectedPackagesList.tsx +54 -25
- package/src/components/preview/ConnectedRepoOverview.tsx +63 -35
- package/src/components/preview/{ConnectedRepoDashboard.tsx → PackageReleasesDashboard.tsx} +33 -71
- package/src/components/preview/index.tsx +20 -77
- package/src/hooks/use-package-builds.ts +87 -0
- package/src/hooks/use-package-release-by-id-or-version.ts +36 -0
- package/src/hooks/use-package-release.ts +32 -0
- package/src/lib/utils/isUuid.ts +5 -0
- package/src/pages/preview-build.tsx +3 -3
- package/src/pages/release-builds.tsx +107 -0
- package/src/pages/release-detail.tsx +118 -0
- package/src/pages/releases.tsx +51 -0
- package/src/pages/view-connected-repo.tsx +0 -18
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import * as ZT from "fake-snippets-api/lib/db/schema"
|
|
2
|
+
|
|
3
|
+
export const publicMapPackageBuild = (
|
|
4
|
+
internalPackageBuild: ZT.PackageBuild,
|
|
5
|
+
options: {
|
|
6
|
+
include_logs?: boolean
|
|
7
|
+
} = {
|
|
8
|
+
include_logs: false,
|
|
9
|
+
},
|
|
10
|
+
): ZT.PackageBuild => {
|
|
11
|
+
const result = {
|
|
12
|
+
...internalPackageBuild,
|
|
13
|
+
created_at: internalPackageBuild.created_at,
|
|
14
|
+
transpilation_started_at: internalPackageBuild.transpilation_started_at,
|
|
15
|
+
transpilation_completed_at: internalPackageBuild.transpilation_completed_at,
|
|
16
|
+
transpilation_logs: options.include_logs
|
|
17
|
+
? internalPackageBuild.transpilation_logs
|
|
18
|
+
: [],
|
|
19
|
+
transpilation_error: internalPackageBuild.transpilation_error,
|
|
20
|
+
circuit_json_build_started_at:
|
|
21
|
+
internalPackageBuild.circuit_json_build_started_at,
|
|
22
|
+
circuit_json_build_completed_at:
|
|
23
|
+
internalPackageBuild.circuit_json_build_completed_at,
|
|
24
|
+
circuit_json_build_logs: options.include_logs
|
|
25
|
+
? internalPackageBuild.circuit_json_build_logs
|
|
26
|
+
: [],
|
|
27
|
+
circuit_json_build_error: internalPackageBuild.circuit_json_build_error,
|
|
28
|
+
build_started_at: internalPackageBuild.build_started_at,
|
|
29
|
+
build_completed_at: internalPackageBuild.build_completed_at,
|
|
30
|
+
build_error: internalPackageBuild.build_error,
|
|
31
|
+
build_error_last_updated_at:
|
|
32
|
+
internalPackageBuild.build_error_last_updated_at,
|
|
33
|
+
preview_url: internalPackageBuild.preview_url,
|
|
34
|
+
build_logs: options.include_logs ? internalPackageBuild.build_logs : null,
|
|
35
|
+
branch_name: internalPackageBuild.branch_name,
|
|
36
|
+
commit_message: internalPackageBuild.commit_message,
|
|
37
|
+
commit_author: internalPackageBuild.commit_author,
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return result
|
|
41
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { withRouteSpec } from "fake-snippets-api/lib/middleware/with-winter-spec"
|
|
2
|
+
import { z } from "zod"
|
|
3
|
+
import { publicMapPackageBuild } from "fake-snippets-api/lib/public-mapping/public-map-package-build"
|
|
4
|
+
|
|
5
|
+
export default withRouteSpec({
|
|
6
|
+
methods: ["GET"],
|
|
7
|
+
auth: "session",
|
|
8
|
+
queryParams: z.object({
|
|
9
|
+
package_build_id: z.string(),
|
|
10
|
+
}),
|
|
11
|
+
jsonResponse: z.object({
|
|
12
|
+
package_build: z.any(),
|
|
13
|
+
}),
|
|
14
|
+
})(async (req, ctx) => {
|
|
15
|
+
const { package_build_id } = req.query
|
|
16
|
+
|
|
17
|
+
if (!package_build_id) {
|
|
18
|
+
return ctx.error(400, {
|
|
19
|
+
error_code: "invalid_request",
|
|
20
|
+
message: "package_build_id is required",
|
|
21
|
+
})
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const packageBuild = ctx.db.packageBuilds.find(
|
|
25
|
+
(build) => build.package_build_id === package_build_id,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
if (!packageBuild) {
|
|
29
|
+
return ctx.error(404, {
|
|
30
|
+
error_code: "package_build_not_found",
|
|
31
|
+
message: "Package build not found",
|
|
32
|
+
})
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const packageRelease = ctx.db.packageReleases.find(
|
|
36
|
+
(pr) => pr.package_release_id === packageBuild.package_release_id,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
if (!packageRelease) {
|
|
40
|
+
return ctx.error(404, {
|
|
41
|
+
error_code: "package_release_not_found",
|
|
42
|
+
message: "Package release not found",
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const pkg = ctx.db.packages.find(
|
|
47
|
+
(p) => p.package_id === packageRelease.package_id,
|
|
48
|
+
)
|
|
49
|
+
if (!pkg) {
|
|
50
|
+
return ctx.error(404, {
|
|
51
|
+
error_code: "package_not_found",
|
|
52
|
+
message: "Package not found",
|
|
53
|
+
})
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (pkg.creator_account_id !== ctx.auth.account_id) {
|
|
57
|
+
return ctx.error(403, {
|
|
58
|
+
error_code: "unauthorized",
|
|
59
|
+
message: "You are not authorized to access this package build",
|
|
60
|
+
})
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const publicBuild = publicMapPackageBuild(packageBuild, {
|
|
64
|
+
include_logs: true,
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
return ctx.json({
|
|
68
|
+
package_build: publicBuild,
|
|
69
|
+
})
|
|
70
|
+
})
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { withRouteSpec } from "fake-snippets-api/lib/middleware/with-winter-spec"
|
|
2
|
+
import { z } from "zod"
|
|
3
|
+
import { publicMapPackageBuild } from "fake-snippets-api/lib/public-mapping/public-map-package-build"
|
|
4
|
+
|
|
5
|
+
export default withRouteSpec({
|
|
6
|
+
methods: ["GET"],
|
|
7
|
+
auth: "session",
|
|
8
|
+
queryParams: z.object({
|
|
9
|
+
package_id: z.string().optional(),
|
|
10
|
+
package_release_id: z.string().optional(),
|
|
11
|
+
}),
|
|
12
|
+
jsonResponse: z.object({
|
|
13
|
+
package_builds: z.array(z.any()),
|
|
14
|
+
}),
|
|
15
|
+
})(async (req, ctx) => {
|
|
16
|
+
const { package_id, package_release_id } = req.query
|
|
17
|
+
if (!package_id && !package_release_id) {
|
|
18
|
+
return ctx.error(400, {
|
|
19
|
+
error_code: "invalid_request",
|
|
20
|
+
message: "Either package_id or package_release_id must be provided",
|
|
21
|
+
})
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
let targetPackageId = package_id
|
|
25
|
+
|
|
26
|
+
if (package_release_id) {
|
|
27
|
+
const packageRelease = ctx.db.packageReleases.find(
|
|
28
|
+
(pr) => pr.package_release_id === package_release_id,
|
|
29
|
+
)
|
|
30
|
+
if (!packageRelease) {
|
|
31
|
+
return ctx.error(404, {
|
|
32
|
+
error_code: "package_release_not_found",
|
|
33
|
+
message: "Package release not found",
|
|
34
|
+
})
|
|
35
|
+
}
|
|
36
|
+
targetPackageId = packageRelease.package_id
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (targetPackageId) {
|
|
40
|
+
const pkg = ctx.db.packages.find((p) => p.package_id === targetPackageId)
|
|
41
|
+
if (!pkg) {
|
|
42
|
+
return ctx.error(404, {
|
|
43
|
+
error_code: "package_not_found",
|
|
44
|
+
message: "Package not found",
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
if (pkg.creator_account_id !== ctx.auth.account_id) {
|
|
48
|
+
return ctx.error(403, {
|
|
49
|
+
error_code: "unauthorized",
|
|
50
|
+
message: "You are not authorized to access this package",
|
|
51
|
+
})
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
let builds = ctx.db.packageBuilds
|
|
56
|
+
|
|
57
|
+
if (package_id) {
|
|
58
|
+
const packageReleases = ctx.db.packageReleases.filter(
|
|
59
|
+
(x) => x.package_id === package_id,
|
|
60
|
+
)
|
|
61
|
+
if (packageReleases.length === 0) {
|
|
62
|
+
return ctx.error(404, {
|
|
63
|
+
error_code: "package_not_found",
|
|
64
|
+
message: "Package not found",
|
|
65
|
+
})
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const packageReleaseIds = packageReleases
|
|
69
|
+
.filter((pr) => pr.package_id === package_id)
|
|
70
|
+
.map((pr) => pr.package_release_id)
|
|
71
|
+
|
|
72
|
+
builds = builds.filter((build) =>
|
|
73
|
+
packageReleaseIds.includes(build.package_release_id),
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (package_release_id) {
|
|
78
|
+
builds = builds.filter(
|
|
79
|
+
(build) => build.package_release_id === package_release_id,
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
builds = builds.sort(
|
|
84
|
+
(a, b) =>
|
|
85
|
+
new Date(b.created_at).getTime() - new Date(a.created_at).getTime(),
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
const publicBuilds = builds.map((build) =>
|
|
89
|
+
publicMapPackageBuild(build, {
|
|
90
|
+
include_logs: false,
|
|
91
|
+
}),
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
return ctx.json({
|
|
95
|
+
package_builds: publicBuilds,
|
|
96
|
+
})
|
|
97
|
+
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tscircuit/fake-snippets",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.107",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
"build:fake-api": "bun run build:fake-api:tsup && bun run build:fake-api:bundle && bun run build:fake-api:schema",
|
|
31
31
|
"build:fake-api:schema": "tsup-node ./fake-snippets-api/lib/db/schema.ts --format esm --dts",
|
|
32
32
|
"generate-images": "bun run scripts/generate-image-sizes.ts",
|
|
33
|
-
"generate-sitemap": "bun run scripts/generate-sitemap.ts"
|
|
33
|
+
"generate-sitemap": "bun run scripts/generate-sitemap.ts",
|
|
34
|
+
"typecheck": "tsc --noEmit"
|
|
34
35
|
},
|
|
35
36
|
"devDependencies": {
|
|
36
37
|
"@anthropic-ai/sdk": "^0.27.3",
|
package/src/App.tsx
CHANGED
|
@@ -79,9 +79,9 @@ const PackageEditorPage = lazyImport(async () => {
|
|
|
79
79
|
])
|
|
80
80
|
return editorModule
|
|
81
81
|
})
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
)
|
|
82
|
+
const ReleasesPage = lazyImport(() => import("@/pages/releases"))
|
|
83
|
+
const ReleaseDetailPage = lazyImport(() => import("@/pages/release-detail"))
|
|
84
|
+
const ReleaseBuildsPage = lazyImport(() => import("@/pages/release-builds"))
|
|
85
85
|
const PreviewBuildPage = lazyImport(() => import("@/pages/preview-build"))
|
|
86
86
|
|
|
87
87
|
class ErrorBoundary extends React.Component<
|
|
@@ -143,7 +143,8 @@ class ErrorBoundary extends React.Component<
|
|
|
143
143
|
this.cleanup() // Clean up listeners before reload
|
|
144
144
|
this.setState({ reloading: true })
|
|
145
145
|
this.reloadTimeout = window.setTimeout(() => {
|
|
146
|
-
|
|
146
|
+
if (window?.location.href.includes("localhost:")) return
|
|
147
|
+
window.location.reload()
|
|
147
148
|
}, 500)
|
|
148
149
|
}
|
|
149
150
|
|
|
@@ -257,7 +258,22 @@ function App() {
|
|
|
257
258
|
<Route path="/my-orders" component={MyOrdersPage} />
|
|
258
259
|
<Route path="/dev-login" component={DevLoginPage} />
|
|
259
260
|
<Route path="/:username" component={UserProfilePage} />
|
|
260
|
-
<Route
|
|
261
|
+
<Route
|
|
262
|
+
path="/:author/:packageName/release/:releaseId/builds"
|
|
263
|
+
component={ReleaseBuildsPage}
|
|
264
|
+
/>
|
|
265
|
+
<Route
|
|
266
|
+
path="/:author/:packageName/release/:releaseId"
|
|
267
|
+
component={ReleaseDetailPage}
|
|
268
|
+
/>
|
|
269
|
+
<Route
|
|
270
|
+
path="/:author/:packageName/releases/:packageReleaseId"
|
|
271
|
+
component={ReleaseDetailPage}
|
|
272
|
+
/>
|
|
273
|
+
<Route
|
|
274
|
+
path="/:author/:packageName/releases"
|
|
275
|
+
component={ReleasesPage}
|
|
276
|
+
/>
|
|
261
277
|
<Route
|
|
262
278
|
path="/build/:buildId/preview"
|
|
263
279
|
component={PreviewBuildPage}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { PrefetchPageLink } from "@/components/PrefetchPageLink"
|
|
2
|
+
import {
|
|
3
|
+
Breadcrumb,
|
|
4
|
+
BreadcrumbList,
|
|
5
|
+
BreadcrumbItem,
|
|
6
|
+
BreadcrumbLink,
|
|
7
|
+
BreadcrumbPage,
|
|
8
|
+
BreadcrumbSeparator,
|
|
9
|
+
} from "@/components/ui/breadcrumb"
|
|
10
|
+
|
|
11
|
+
interface PackageBreadcrumbProps {
|
|
12
|
+
author: string
|
|
13
|
+
packageName: string
|
|
14
|
+
unscopedName?: string
|
|
15
|
+
currentPage?: "releases" | "builds" | string
|
|
16
|
+
releaseVersion?: string
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function PackageBreadcrumb({
|
|
20
|
+
author,
|
|
21
|
+
packageName,
|
|
22
|
+
unscopedName,
|
|
23
|
+
currentPage,
|
|
24
|
+
releaseVersion,
|
|
25
|
+
}: PackageBreadcrumbProps) {
|
|
26
|
+
return (
|
|
27
|
+
<Breadcrumb className="mb-4">
|
|
28
|
+
<BreadcrumbList>
|
|
29
|
+
{/* Author */}
|
|
30
|
+
<BreadcrumbItem>
|
|
31
|
+
<BreadcrumbLink asChild>
|
|
32
|
+
<PrefetchPageLink href={`/${author}`}>{author}</PrefetchPageLink>
|
|
33
|
+
</BreadcrumbLink>
|
|
34
|
+
</BreadcrumbItem>
|
|
35
|
+
<BreadcrumbSeparator>
|
|
36
|
+
<span>/</span>
|
|
37
|
+
</BreadcrumbSeparator>
|
|
38
|
+
|
|
39
|
+
{/* Package */}
|
|
40
|
+
<BreadcrumbItem>
|
|
41
|
+
<BreadcrumbLink asChild>
|
|
42
|
+
<PrefetchPageLink href={`/${packageName}`}>
|
|
43
|
+
{unscopedName || packageName}
|
|
44
|
+
</PrefetchPageLink>
|
|
45
|
+
</BreadcrumbLink>
|
|
46
|
+
</BreadcrumbItem>
|
|
47
|
+
<BreadcrumbSeparator>
|
|
48
|
+
<span>/</span>
|
|
49
|
+
</BreadcrumbSeparator>
|
|
50
|
+
|
|
51
|
+
{/* Releases */}
|
|
52
|
+
{(currentPage === "releases" ||
|
|
53
|
+
releaseVersion ||
|
|
54
|
+
currentPage === "builds") && (
|
|
55
|
+
<>
|
|
56
|
+
<BreadcrumbItem>
|
|
57
|
+
{currentPage === "releases" ? (
|
|
58
|
+
<BreadcrumbPage>releases</BreadcrumbPage>
|
|
59
|
+
) : (
|
|
60
|
+
<BreadcrumbLink asChild>
|
|
61
|
+
<PrefetchPageLink href={`/${packageName}/releases`}>
|
|
62
|
+
releases
|
|
63
|
+
</PrefetchPageLink>
|
|
64
|
+
</BreadcrumbLink>
|
|
65
|
+
)}
|
|
66
|
+
</BreadcrumbItem>
|
|
67
|
+
<BreadcrumbSeparator>
|
|
68
|
+
<span>/</span>
|
|
69
|
+
</BreadcrumbSeparator>
|
|
70
|
+
</>
|
|
71
|
+
)}
|
|
72
|
+
|
|
73
|
+
{/* Release Version */}
|
|
74
|
+
{releaseVersion && (
|
|
75
|
+
<>
|
|
76
|
+
<BreadcrumbItem>
|
|
77
|
+
{currentPage === "builds" ? (
|
|
78
|
+
<BreadcrumbLink asChild>
|
|
79
|
+
<PrefetchPageLink
|
|
80
|
+
href={`/${packageName}/release/${releaseVersion}`}
|
|
81
|
+
>
|
|
82
|
+
{releaseVersion}
|
|
83
|
+
</PrefetchPageLink>
|
|
84
|
+
</BreadcrumbLink>
|
|
85
|
+
) : (
|
|
86
|
+
<BreadcrumbPage>{releaseVersion}</BreadcrumbPage>
|
|
87
|
+
)}
|
|
88
|
+
</BreadcrumbItem>
|
|
89
|
+
{currentPage === "builds" && (
|
|
90
|
+
<>
|
|
91
|
+
<BreadcrumbSeparator>
|
|
92
|
+
<span>/</span>
|
|
93
|
+
</BreadcrumbSeparator>
|
|
94
|
+
<BreadcrumbItem>
|
|
95
|
+
<BreadcrumbPage>builds</BreadcrumbPage>
|
|
96
|
+
</BreadcrumbItem>
|
|
97
|
+
</>
|
|
98
|
+
)}
|
|
99
|
+
</>
|
|
100
|
+
)}
|
|
101
|
+
|
|
102
|
+
{/* Other current pages */}
|
|
103
|
+
{currentPage && !["releases", "builds"].includes(currentPage) && (
|
|
104
|
+
<BreadcrumbItem>
|
|
105
|
+
<BreadcrumbPage>{currentPage}</BreadcrumbPage>
|
|
106
|
+
</BreadcrumbItem>
|
|
107
|
+
)}
|
|
108
|
+
</BreadcrumbList>
|
|
109
|
+
</Breadcrumb>
|
|
110
|
+
)
|
|
111
|
+
}
|
|
@@ -5,12 +5,9 @@ import { usePackageReleaseById } from "@/hooks/use-package-release"
|
|
|
5
5
|
import { timeAgo } from "@/lib/utils/timeAgo"
|
|
6
6
|
import { BuildStatus, BuildStep } from "./build-status"
|
|
7
7
|
import type { PackageRelease } from "fake-snippets-api/lib/db/schema"
|
|
8
|
-
import {
|
|
9
|
-
getBuildStatus,
|
|
10
|
-
getLatestBuildFromPackageRelease,
|
|
11
|
-
StatusIcon,
|
|
12
|
-
} from "@/components/preview"
|
|
8
|
+
import { getBuildStatus, StatusIcon } from "@/components/preview"
|
|
13
9
|
import { PrefetchPageLink } from "@/components/PrefetchPageLink"
|
|
10
|
+
import { usePackageBuild } from "@/hooks/use-package-builds"
|
|
14
11
|
|
|
15
12
|
function getTranspilationStatus(
|
|
16
13
|
pr?: PackageRelease | null,
|
|
@@ -45,6 +42,9 @@ export default function SidebarReleasesSection() {
|
|
|
45
42
|
const { data: packageRelease } = usePackageReleaseById(
|
|
46
43
|
packageInfo?.latest_package_release_id,
|
|
47
44
|
)
|
|
45
|
+
const { data: latestBuild } = usePackageBuild(
|
|
46
|
+
packageRelease?.latest_package_build_id ?? null,
|
|
47
|
+
)
|
|
48
48
|
|
|
49
49
|
const buildSteps: BuildStep[] = [
|
|
50
50
|
{
|
|
@@ -74,16 +74,27 @@ export default function SidebarReleasesSection() {
|
|
|
74
74
|
)
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
const
|
|
78
|
-
|
|
77
|
+
const { status, label } = latestBuild
|
|
78
|
+
? getBuildStatus(latestBuild)
|
|
79
|
+
: { status: "pending", label: "pending" }
|
|
79
80
|
return (
|
|
80
81
|
<div className="mb-6">
|
|
81
|
-
<h2 className="text-lg font-semibold mb-2">
|
|
82
|
+
<h2 className="text-lg font-semibold mb-2">
|
|
83
|
+
<PrefetchPageLink
|
|
84
|
+
href={`/${packageInfo?.owner_github_username}/${packageInfo?.unscoped_name}/releases`}
|
|
85
|
+
className="hover:underline"
|
|
86
|
+
>
|
|
87
|
+
Releases
|
|
88
|
+
</PrefetchPageLink>
|
|
89
|
+
</h2>
|
|
82
90
|
<div className="flex flex-col space-y-2">
|
|
83
|
-
<
|
|
91
|
+
<PrefetchPageLink
|
|
92
|
+
href={`/${packageInfo?.owner_github_username}/${packageInfo?.unscoped_name}/releases`}
|
|
93
|
+
className="flex items-center hover:underline"
|
|
94
|
+
>
|
|
84
95
|
<Tag className="h-4 w-4 mr-2 text-gray-500 dark:text-[#8b949e]" />
|
|
85
96
|
<span className="text-sm font-medium">v{packageRelease.version}</span>
|
|
86
|
-
</
|
|
97
|
+
</PrefetchPageLink>
|
|
87
98
|
<div className="flex items-center">
|
|
88
99
|
<Clock className="h-4 w-4 mr-2 text-gray-500 dark:text-[#8b949e]" />
|
|
89
100
|
<span className="text-sm text-gray-500 dark:text-[#8b949e]">
|
|
@@ -103,7 +114,7 @@ export default function SidebarReleasesSection() {
|
|
|
103
114
|
className="flex items-center gap-2 text-sm text-gray-500 dark:text-[#8b949e]"
|
|
104
115
|
>
|
|
105
116
|
<StatusIcon status={status} />
|
|
106
|
-
<span>Package
|
|
117
|
+
<span>Package Preview {label}</span>
|
|
107
118
|
</PrefetchPageLink>
|
|
108
119
|
)}
|
|
109
120
|
</div>
|