@tscircuit/fake-snippets 0.0.96 → 0.0.97
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/api/generated-index.js +8 -0
- package/bun.lock +36 -32
- package/dist/bundle.js +32 -7
- package/fake-snippets-api/routes/api/package_releases/rebuild.ts +39 -5
- package/package.json +4 -4
- package/src/components/DownloadButtonAndMenu.tsx +6 -6
- package/src/components/PackageCard.tsx +5 -33
- package/src/components/ViewPackagePage/components/main-content-header.tsx +1 -1
- package/src/components/dialogs/confirm-delete-package-dialog.tsx +19 -6
- package/src/hooks/use-rebuild-package-release-mutation.ts +2 -2
- package/src/pages/datasheets.tsx +19 -1
|
@@ -1,20 +1,26 @@
|
|
|
1
1
|
import { withRouteSpec } from "fake-snippets-api/lib/middleware/with-winter-spec"
|
|
2
|
-
import { packageReleaseSchema } from "fake-snippets-api/lib/db/schema"
|
|
3
2
|
import { z } from "zod"
|
|
3
|
+
import Debug from "debug"
|
|
4
|
+
|
|
5
|
+
const debug = Debug("fake-snippets-api:rebuild-package")
|
|
4
6
|
|
|
5
7
|
export default withRouteSpec({
|
|
6
8
|
methods: ["POST"],
|
|
7
9
|
auth: "session",
|
|
8
10
|
jsonBody: z.object({
|
|
9
11
|
package_release_id: z.string(),
|
|
12
|
+
rebuild_transpilation: z.boolean().default(true),
|
|
13
|
+
rebuild_circuit_json: z.boolean().default(true),
|
|
10
14
|
}),
|
|
11
15
|
jsonResponse: z.object({
|
|
12
16
|
ok: z.boolean(),
|
|
13
|
-
package_release: packageReleaseSchema,
|
|
14
17
|
}),
|
|
15
18
|
})(async (req, ctx) => {
|
|
16
|
-
const { package_release_id } =
|
|
19
|
+
const { package_release_id, rebuild_transpilation, rebuild_circuit_json } =
|
|
20
|
+
req.jsonBody
|
|
17
21
|
|
|
22
|
+
debug("jsonBody", req.jsonBody)
|
|
23
|
+
// Get the package release info for logging
|
|
18
24
|
const release = ctx.db.getPackageReleaseById(package_release_id)
|
|
19
25
|
|
|
20
26
|
if (!release) {
|
|
@@ -24,9 +30,37 @@ export default withRouteSpec({
|
|
|
24
30
|
})
|
|
25
31
|
}
|
|
26
32
|
|
|
27
|
-
|
|
33
|
+
const packageInfo = ctx.db.getPackageById(release.package_id)
|
|
34
|
+
|
|
35
|
+
if (!packageInfo) {
|
|
36
|
+
return ctx.error(404, {
|
|
37
|
+
error_code: "package_not_found",
|
|
38
|
+
message: "Package not found",
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (packageInfo.owner_org_id !== ctx.auth.personal_org_id) {
|
|
43
|
+
return ctx.error(403, {
|
|
44
|
+
error_code: "forbidden",
|
|
45
|
+
message: "You do not have permission to rebuild this package release",
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
debug(
|
|
50
|
+
`Rebuilding package release ${package_release_id} for ${packageInfo.name}@${release.version}`,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
// Trigger transpilation if requested
|
|
54
|
+
if (rebuild_transpilation) {
|
|
55
|
+
debug("Resetting transpilation state")
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Set circuit JSON build state to pending for worker pickup if requested
|
|
59
|
+
if (rebuild_circuit_json) {
|
|
60
|
+
debug("Resetting circuit JSON build state")
|
|
61
|
+
}
|
|
62
|
+
|
|
28
63
|
return ctx.json({
|
|
29
64
|
ok: true,
|
|
30
|
-
package_release: release,
|
|
31
65
|
})
|
|
32
66
|
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tscircuit/fake-snippets",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.97",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
"circuit-json-to-pnp-csv": "^0.0.7",
|
|
110
110
|
"circuit-json-to-readable-netlist": "^0.0.13",
|
|
111
111
|
"circuit-json-to-tscircuit": "^0.0.4",
|
|
112
|
-
"circuit-to-svg": "^0.0.
|
|
112
|
+
"circuit-to-svg": "^0.0.167",
|
|
113
113
|
"class-variance-authority": "^0.7.1",
|
|
114
114
|
"clsx": "^2.1.1",
|
|
115
115
|
"cmdk": "^1.0.4",
|
|
@@ -162,7 +162,7 @@
|
|
|
162
162
|
"redaxios": "^0.5.1",
|
|
163
163
|
"remark-gfm": "^4.0.1",
|
|
164
164
|
"rollup-plugin-visualizer": "^5.12.0",
|
|
165
|
-
"schematic-symbols": "^0.0.
|
|
165
|
+
"schematic-symbols": "^0.0.171",
|
|
166
166
|
"sharp": "^0.33.5",
|
|
167
167
|
"shiki": "^3.2.1",
|
|
168
168
|
"sitemap": "^8.0.0",
|
|
@@ -174,7 +174,7 @@
|
|
|
174
174
|
"terser": "^5.27.0",
|
|
175
175
|
"three": "^0.177.0",
|
|
176
176
|
"three-stdlib": "^2.36.0",
|
|
177
|
-
"tscircuit": "^0.0.
|
|
177
|
+
"tscircuit": "^0.0.538",
|
|
178
178
|
"tsup": "^8.5.0",
|
|
179
179
|
"typescript": "^5.6.3",
|
|
180
180
|
"use-async-memo": "^1.2.5",
|
|
@@ -49,11 +49,11 @@ export function DownloadButtonAndMenu({
|
|
|
49
49
|
<Button
|
|
50
50
|
disabled
|
|
51
51
|
size="sm"
|
|
52
|
-
className="
|
|
52
|
+
className="shadow-none bg-muted text-muted-foreground border border-input cursor-not-allowed"
|
|
53
53
|
>
|
|
54
|
-
<Download className="h-4 w-4 mr-
|
|
54
|
+
<Download className="h-4 w-4 mr-2" />
|
|
55
55
|
Download
|
|
56
|
-
<ChevronDown className="h-4 w-4 ml-
|
|
56
|
+
<ChevronDown className="h-4 w-4 ml-1" />
|
|
57
57
|
</Button>
|
|
58
58
|
</div>
|
|
59
59
|
)
|
|
@@ -65,11 +65,11 @@ export function DownloadButtonAndMenu({
|
|
|
65
65
|
<DropdownMenuTrigger asChild>
|
|
66
66
|
<Button
|
|
67
67
|
size="sm"
|
|
68
|
-
className="bg-
|
|
68
|
+
className="bg-white shadow-none text-gray-900 hover:bg-gray-100 border border-gray-300 px-1 pl-2"
|
|
69
69
|
>
|
|
70
|
-
<Download className="
|
|
70
|
+
<Download className="w-4 h-4 mr-2" />
|
|
71
71
|
Download
|
|
72
|
-
<ChevronDown className="
|
|
72
|
+
<ChevronDown className="w-4 h-4 ml-1" />
|
|
73
73
|
</Button>
|
|
74
74
|
</DropdownMenuTrigger>
|
|
75
75
|
<DropdownMenuContent className="!z-[101]">
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
import { SnippetType, SnippetTypeIcon } from "./SnippetTypeIcon"
|
|
21
21
|
import { timeAgo } from "@/lib/utils/timeAgo"
|
|
22
22
|
import { ImageWithFallback } from "./ImageWithFallback"
|
|
23
|
-
import {
|
|
23
|
+
import { useCopyToClipboard } from "@/hooks/use-copy-to-clipboard"
|
|
24
24
|
|
|
25
25
|
export interface PackageCardProps {
|
|
26
26
|
/** The package data to display */
|
|
@@ -57,7 +57,6 @@ export const PackageCard: React.FC<PackageCardProps> = ({
|
|
|
57
57
|
withLink = true,
|
|
58
58
|
renderActions,
|
|
59
59
|
}) => {
|
|
60
|
-
const { toast } = useToast()
|
|
61
60
|
const handleDeleteClick = (e: React.MouseEvent) => {
|
|
62
61
|
e.preventDefault() // Prevent navigation
|
|
63
62
|
if (onDeleteClick) {
|
|
@@ -65,39 +64,12 @@ export const PackageCard: React.FC<PackageCardProps> = ({
|
|
|
65
64
|
}
|
|
66
65
|
}
|
|
67
66
|
|
|
68
|
-
const
|
|
69
|
-
e.preventDefault()
|
|
67
|
+
const { copyToClipboard } = useCopyToClipboard()
|
|
70
68
|
|
|
69
|
+
const handleShareClick = (e: React.MouseEvent) => {
|
|
70
|
+
e.preventDefault()
|
|
71
71
|
const shareUrl = `${window.location.origin}/${pkg.owner_github_username}/${pkg.unscoped_name}`
|
|
72
|
-
|
|
73
|
-
`Explore this tscircuit package: ${pkg.unscoped_name} by ${pkg.owner_github_username}${pkg.description ? ` - ${pkg.description}` : ""}`.trim()
|
|
74
|
-
if (navigator.share) {
|
|
75
|
-
await navigator
|
|
76
|
-
.share({
|
|
77
|
-
title: shareText,
|
|
78
|
-
text: shareText,
|
|
79
|
-
url: shareUrl,
|
|
80
|
-
})
|
|
81
|
-
.catch(() => fallbackShare(shareText, shareUrl))
|
|
82
|
-
} else {
|
|
83
|
-
fallbackShare(shareText, shareUrl)
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const fallbackShare = (text: string, url: string) => {
|
|
88
|
-
const shareContent = `${text}\n${url}`
|
|
89
|
-
navigator.clipboard
|
|
90
|
-
.writeText(shareContent)
|
|
91
|
-
.then(() => {
|
|
92
|
-
toast({
|
|
93
|
-
title: "Share content copied to clipboard",
|
|
94
|
-
})
|
|
95
|
-
})
|
|
96
|
-
.catch(() => {
|
|
97
|
-
toast({
|
|
98
|
-
title: "Unable to share or copy to clipboard",
|
|
99
|
-
})
|
|
100
|
-
})
|
|
72
|
+
copyToClipboard(shareUrl)
|
|
101
73
|
}
|
|
102
74
|
|
|
103
75
|
const availableImages = ["pcb", "schematic", "assembly", "3d"]
|
|
@@ -94,7 +94,7 @@ export default function MainContentHeader({
|
|
|
94
94
|
<DropdownMenuTrigger asChild>
|
|
95
95
|
<Button
|
|
96
96
|
size="sm"
|
|
97
|
-
className="bg-green-600
|
|
97
|
+
className="bg-green-600 hover:bg-green-700 dark:bg-[#238636] dark:hover:bg-[#2ea043] text-white"
|
|
98
98
|
>
|
|
99
99
|
<CodeIcon className="h-4 w-4 mr-1.5" />
|
|
100
100
|
Code
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
Dialog,
|
|
3
|
+
DialogContent,
|
|
4
|
+
DialogHeader,
|
|
5
|
+
DialogTitle,
|
|
6
|
+
DialogDescription,
|
|
7
|
+
} from "../ui/dialog"
|
|
2
8
|
import { Button } from "../ui/button"
|
|
3
9
|
import { createUseDialog } from "./create-use-dialog"
|
|
4
10
|
import { useDeletePackage } from "@/hooks/use-delete-package"
|
|
@@ -33,13 +39,20 @@ export const ConfirmDeletePackageDialog = ({
|
|
|
33
39
|
|
|
34
40
|
return (
|
|
35
41
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
36
|
-
<DialogContent className="w-[90vw]">
|
|
42
|
+
<DialogContent className="w-[90vw] p-6 rounded-2xl shadow-lg">
|
|
37
43
|
<DialogHeader>
|
|
38
|
-
<DialogTitle
|
|
44
|
+
<DialogTitle className="text-left">
|
|
45
|
+
Confirm Delete Package
|
|
46
|
+
</DialogTitle>
|
|
47
|
+
<DialogDescription className="text-left">
|
|
48
|
+
Are you sure you want to delete the package{" "}
|
|
49
|
+
<span className="font-bold">{packageName}</span>?
|
|
50
|
+
</DialogDescription>
|
|
39
51
|
</DialogHeader>
|
|
40
|
-
<p
|
|
41
|
-
|
|
42
|
-
|
|
52
|
+
<p className="text-red-600 font-medium">
|
|
53
|
+
This action cannot be undone.
|
|
54
|
+
</p>
|
|
55
|
+
<div className="flex justify-end gap-4 mt-6">
|
|
43
56
|
<Button variant="outline" onClick={() => onOpenChange(false)}>
|
|
44
57
|
Cancel
|
|
45
58
|
</Button>
|
|
@@ -30,8 +30,8 @@ export const useRebuildPackageReleaseMutation = ({
|
|
|
30
30
|
toast({
|
|
31
31
|
title: "Error",
|
|
32
32
|
description:
|
|
33
|
-
error?.response?.data?.message ||
|
|
34
|
-
error?.data?.message ||
|
|
33
|
+
error?.response?.data?.error?.message ||
|
|
34
|
+
error?.data?.error?.message ||
|
|
35
35
|
"Failed to rebuild package.",
|
|
36
36
|
variant: "destructive",
|
|
37
37
|
})
|
package/src/pages/datasheets.tsx
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import React, { useState } from "react"
|
|
2
2
|
import { useQuery } from "react-query"
|
|
3
3
|
import { useAxios } from "@/hooks/use-axios"
|
|
4
|
+
import { useCreateDatasheet } from "@/hooks/use-create-datasheet"
|
|
4
5
|
import Header from "@/components/Header"
|
|
5
6
|
import Footer from "@/components/Footer"
|
|
6
7
|
import { Input } from "@/components/ui/input"
|
|
7
8
|
import { Search } from "lucide-react"
|
|
8
|
-
import { Link } from "wouter"
|
|
9
|
+
import { Link, useLocation } from "wouter"
|
|
9
10
|
|
|
10
11
|
interface DatasheetSummary {
|
|
11
12
|
datasheet_id: string
|
|
@@ -14,6 +15,10 @@ interface DatasheetSummary {
|
|
|
14
15
|
|
|
15
16
|
export const DatasheetsPage: React.FC = () => {
|
|
16
17
|
const axios = useAxios()
|
|
18
|
+
const [, navigate] = useLocation()
|
|
19
|
+
const createDatasheet = useCreateDatasheet({
|
|
20
|
+
onSuccess: (datasheet) => navigate(`/datasheets/${datasheet.chip_name}`),
|
|
21
|
+
})
|
|
17
22
|
const [searchQuery, setSearchQuery] = useState("")
|
|
18
23
|
|
|
19
24
|
const {
|
|
@@ -119,6 +124,19 @@ export const DatasheetsPage: React.FC = () => {
|
|
|
119
124
|
? `No datasheets match your search for "${searchQuery}".`
|
|
120
125
|
: "There are no popular datasheets at the moment."}
|
|
121
126
|
</p>
|
|
127
|
+
{searchQuery && (
|
|
128
|
+
<button
|
|
129
|
+
className="mt-2 px-4 py-2 bg-blue-500 text-white rounded"
|
|
130
|
+
onClick={() =>
|
|
131
|
+
createDatasheet.mutate({ chip_name: searchQuery })
|
|
132
|
+
}
|
|
133
|
+
disabled={createDatasheet.isLoading}
|
|
134
|
+
>
|
|
135
|
+
{createDatasheet.isLoading
|
|
136
|
+
? "Creating..."
|
|
137
|
+
: `Create Datasheet for ${searchQuery}`}
|
|
138
|
+
</button>
|
|
139
|
+
)}
|
|
122
140
|
</div>
|
|
123
141
|
)}
|
|
124
142
|
</main>
|