@tscircuit/fake-snippets 0.0.72 → 0.0.74
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/bun.lock +33 -17
- package/dist/bundle.js +296 -200
- package/dist/index.d.ts +87 -4
- package/dist/index.js +71 -8
- package/dist/schema.d.ts +120 -0
- package/dist/schema.js +19 -1
- package/fake-snippets-api/lib/db/db-client.ts +58 -7
- package/fake-snippets-api/lib/db/schema.ts +26 -0
- package/fake-snippets-api/lib/package_file/generate-fs-sha.ts +20 -0
- package/fake-snippets-api/lib/public-mapping/public-map-package.ts +1 -0
- package/fake-snippets-api/routes/api/package_files/create.ts +3 -0
- package/fake-snippets-api/routes/api/package_files/create_or_update.ts +6 -0
- package/fake-snippets-api/routes/api/package_files/delete.ts +3 -0
- package/fake-snippets-api/routes/api/package_releases/rebuild.ts +32 -0
- package/fake-snippets-api/routes/api/packages/create.ts +1 -0
- package/package.json +7 -7
- package/src/App.tsx +5 -0
- package/src/components/JLCPCBImportDialog.tsx +1 -1
- package/src/components/PackageBuildsPage/PackageBuildDetailsPage.tsx +56 -0
- package/src/components/PackageBuildsPage/build-preview-content.tsx +11 -0
- package/src/components/PackageBuildsPage/collapsible-section.tsx +70 -0
- package/src/components/PackageBuildsPage/package-build-details-panel.tsx +84 -0
- package/src/components/PackageBuildsPage/package-build-header.tsx +75 -0
- package/src/components/PackageCard.tsx +1 -10
- package/src/components/TrendingPackagesCarousel.tsx +5 -16
- package/src/components/ViewPackagePage/components/mobile-sidebar.tsx +1 -1
- package/src/components/ViewPackagePage/components/preview-image-squares.tsx +2 -6
- package/src/components/package-port/CodeAndPreview.tsx +3 -2
- package/src/components/package-port/CodeEditor.tsx +5 -3
- package/src/components/package-port/EditorNav.tsx +17 -13
- package/src/hooks/use-create-package-mutation.ts +0 -7
- package/src/hooks/use-current-package-id.ts +2 -8
- package/src/hooks/use-current-package-release.ts +28 -0
- package/src/hooks/use-preview-images.ts +3 -15
- package/src/hooks/useFileManagement.ts +26 -21
- package/src/lib/utils/checkIfManualEditsImported.ts +9 -0
- package/src/pages/editor.tsx +2 -10
- package/src/pages/package-builds.tsx +33 -0
- package/src/pages/package-editor.tsx +2 -14
- package/src/hooks/use-get-fsmap-hash-for-package.ts +0 -19
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
} from "@/components/ui/dropdown-menu"
|
|
13
13
|
import { SnippetType, SnippetTypeIcon } from "./SnippetTypeIcon"
|
|
14
14
|
import { timeAgo } from "@/lib/utils/timeAgo"
|
|
15
|
-
import { useGetFsMapHashForPackage } from "@/hooks/use-get-fsmap-hash-for-package"
|
|
16
15
|
import { ImageWithFallback } from "./ImageWithFallback"
|
|
17
16
|
|
|
18
17
|
export interface PackageCardProps {
|
|
@@ -57,10 +56,6 @@ export const PackageCard: React.FC<PackageCardProps> = ({
|
|
|
57
56
|
}
|
|
58
57
|
}
|
|
59
58
|
|
|
60
|
-
const fsMapHash = useGetFsMapHashForPackage(
|
|
61
|
-
pkg.latest_package_release_id ?? "",
|
|
62
|
-
)
|
|
63
|
-
|
|
64
59
|
const cardContent = (
|
|
65
60
|
<div
|
|
66
61
|
className={`border p-4 rounded-md hover:shadow-md transition-shadow flex flex-col gap-4 ${className}`}
|
|
@@ -70,11 +65,7 @@ export const PackageCard: React.FC<PackageCardProps> = ({
|
|
|
70
65
|
className={`${imageSize} flex-shrink-0 rounded-md overflow-hidden`}
|
|
71
66
|
>
|
|
72
67
|
<ImageWithFallback
|
|
73
|
-
src={`${baseUrl}/packages/images/${pkg.owner_github_username}/${pkg.unscoped_name}/pcb.svg
|
|
74
|
-
{
|
|
75
|
-
fs_sha: fsMapHash ?? "",
|
|
76
|
-
},
|
|
77
|
-
).toString()}`}
|
|
68
|
+
src={`${baseUrl}/packages/images/${pkg.owner_github_username}/${pkg.unscoped_name}/pcb.svg?fs_sha=${pkg.latest_package_release_fs_sha}`}
|
|
78
69
|
alt={`${pkg.unscoped_name} PCB image`}
|
|
79
70
|
className={`object-cover h-full w-full ${imageTransform}`}
|
|
80
71
|
/>
|
|
@@ -5,16 +5,11 @@ import { Link } from "wouter"
|
|
|
5
5
|
import { Package } from "fake-snippets-api/lib/db/schema"
|
|
6
6
|
import { useRef, useState } from "react"
|
|
7
7
|
import { useSnippetsBaseApiUrl } from "@/hooks/use-snippets-base-api-url"
|
|
8
|
-
import { useGetFsMapHashForPackage } from "@/hooks/use-get-fsmap-hash-for-package"
|
|
9
8
|
|
|
10
9
|
const CarouselItem = ({
|
|
11
10
|
pkg,
|
|
12
11
|
apiBaseUrl,
|
|
13
12
|
}: { pkg: Package; apiBaseUrl: string }) => {
|
|
14
|
-
const fsMapHash = useGetFsMapHashForPackage(
|
|
15
|
-
pkg.latest_package_release_id ?? "",
|
|
16
|
-
)
|
|
17
|
-
|
|
18
13
|
return (
|
|
19
14
|
<Link href={`/${pkg.owner_github_username}/${pkg.unscoped_name}`}>
|
|
20
15
|
<div className="flex-shrink-0 w-[200px] bg-white p-3 py-2 rounded-lg shadow-sm border border-gray-200 hover:border-gray-300 transition-colors">
|
|
@@ -22,17 +17,11 @@ const CarouselItem = ({
|
|
|
22
17
|
{pkg.owner_github_username}/{pkg.unscoped_name}
|
|
23
18
|
</div>
|
|
24
19
|
<div className="mb-2 h-24 w-full bg-black rounded overflow-hidden">
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
},
|
|
31
|
-
).toString()}`}
|
|
32
|
-
alt="PCB preview"
|
|
33
|
-
className="w-full h-full object-contain p-2 scale-[3] rotate-45 hover:scale-[3.5] transition-transform"
|
|
34
|
-
/>
|
|
35
|
-
)}
|
|
20
|
+
<img
|
|
21
|
+
src={`${apiBaseUrl}/packages/images/${pkg.owner_github_username}/${pkg.unscoped_name}/pcb.svg?fs_map=${pkg.latest_package_release_fs_sha}`}
|
|
22
|
+
alt="PCB preview"
|
|
23
|
+
className="w-full h-full object-contain p-2 scale-[3] rotate-45 hover:scale-[3.5] transition-transform"
|
|
24
|
+
/>
|
|
36
25
|
</div>
|
|
37
26
|
<div className="flex items-center text-xs text-gray-500">
|
|
38
27
|
<StarFilledIcon className="w-3 h-3 mr-1" />
|
|
@@ -72,7 +72,7 @@ const MobileSidebar = ({
|
|
|
72
72
|
|
|
73
73
|
const { availableViews } = usePreviewImages({
|
|
74
74
|
packageName: packageInfo?.name,
|
|
75
|
-
fsMapHash: packageInfo?.
|
|
75
|
+
fsMapHash: packageInfo?.latest_package_release_fs_sha ?? "",
|
|
76
76
|
})
|
|
77
77
|
|
|
78
78
|
const handleViewClick = useCallback(
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
import { Skeleton } from "@/components/ui/skeleton"
|
|
3
|
-
import { useGetFsMapHashForPackage } from "@/hooks/use-get-fsmap-hash-for-package"
|
|
4
3
|
import { usePreviewImages } from "@/hooks/use-preview-images"
|
|
5
4
|
import type { Package } from "fake-snippets-api/lib/db/schema"
|
|
6
5
|
|
|
7
6
|
interface ViewPlaceholdersProps {
|
|
8
|
-
packageInfo?: Pick<Package, "name" | "
|
|
7
|
+
packageInfo?: Pick<Package, "name" | "latest_package_release_fs_sha">
|
|
9
8
|
onViewChange?: (view: "3d" | "pcb" | "schematic") => void
|
|
10
9
|
}
|
|
11
10
|
|
|
@@ -13,12 +12,9 @@ export default function PreviewImageSquares({
|
|
|
13
12
|
packageInfo,
|
|
14
13
|
onViewChange,
|
|
15
14
|
}: ViewPlaceholdersProps) {
|
|
16
|
-
const fsMapHash = useGetFsMapHashForPackage(
|
|
17
|
-
packageInfo?.latest_package_release_id ?? "",
|
|
18
|
-
)
|
|
19
15
|
const { availableViews } = usePreviewImages({
|
|
20
16
|
packageName: packageInfo?.name,
|
|
21
|
-
fsMapHash:
|
|
17
|
+
fsMapHash: packageInfo?.latest_package_release_fs_sha ?? "",
|
|
22
18
|
})
|
|
23
19
|
|
|
24
20
|
const handleViewClick = (viewId: string) => {
|
|
@@ -164,9 +164,9 @@ export function CodeAndPreview({ pkg }: Props) {
|
|
|
164
164
|
)
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
-
if ((!pkg
|
|
167
|
+
if (urlParams.package_id && (!pkg || isLoading)) {
|
|
168
168
|
return (
|
|
169
|
-
<div className="flex items-center justify-center h-
|
|
169
|
+
<div className="flex items-center justify-center h-[60vh]">
|
|
170
170
|
<div className="flex flex-col items-center justify-center">
|
|
171
171
|
<div className="text-lg text-gray-500 mb-4">Loading</div>
|
|
172
172
|
<Loader2 className="w-16 h-16 animate-spin text-gray-400" />
|
|
@@ -200,6 +200,7 @@ export function CodeAndPreview({ pkg }: Props) {
|
|
|
200
200
|
)}
|
|
201
201
|
>
|
|
202
202
|
<CodeEditor
|
|
203
|
+
isSaving={isSaving}
|
|
203
204
|
handleCreateFile={createFile}
|
|
204
205
|
handleDeleteFile={deleteFile}
|
|
205
206
|
currentFile={currentFile}
|
|
@@ -49,6 +49,7 @@ export const CodeEditor = ({
|
|
|
49
49
|
onCodeChange,
|
|
50
50
|
readOnly = false,
|
|
51
51
|
files = [],
|
|
52
|
+
isSaving = false,
|
|
52
53
|
isStreaming = false,
|
|
53
54
|
showImportAndFormatButtons = true,
|
|
54
55
|
onFileContentChanged,
|
|
@@ -60,6 +61,7 @@ export const CodeEditor = ({
|
|
|
60
61
|
}: {
|
|
61
62
|
onCodeChange: (code: string, filename?: string) => void
|
|
62
63
|
files: PackageFile[]
|
|
64
|
+
isSaving?: boolean
|
|
63
65
|
handleCreateFile: (props: ICreateFileProps) => ICreateFileResult
|
|
64
66
|
handleDeleteFile: (props: IDeleteFileProps) => IDeleteFileResult
|
|
65
67
|
readOnly?: boolean
|
|
@@ -242,7 +244,7 @@ export const CodeEditor = ({
|
|
|
242
244
|
? json()
|
|
243
245
|
: javascript({ typescript: true, jsx: true }),
|
|
244
246
|
keymap.of([indentWithTab]),
|
|
245
|
-
EditorState.readOnly.of(readOnly),
|
|
247
|
+
EditorState.readOnly.of(readOnly || isSaving),
|
|
246
248
|
EditorView.updateListener.of((update) => {
|
|
247
249
|
if (update.docChanged) {
|
|
248
250
|
const newContent = update.state.doc.toString()
|
|
@@ -416,7 +418,7 @@ export const CodeEditor = ({
|
|
|
416
418
|
const end = start + match[0].length
|
|
417
419
|
decorations.push(
|
|
418
420
|
Decoration.mark({
|
|
419
|
-
class: "cm-underline",
|
|
421
|
+
class: "cm-underline cursor-pointer",
|
|
420
422
|
}).range(start, end),
|
|
421
423
|
)
|
|
422
424
|
}
|
|
@@ -448,7 +450,7 @@ export const CodeEditor = ({
|
|
|
448
450
|
return () => {
|
|
449
451
|
view.destroy()
|
|
450
452
|
}
|
|
451
|
-
}, [!isStreaming, currentFile, code !== "", Boolean(highlighter)])
|
|
453
|
+
}, [!isStreaming, currentFile, code !== "", Boolean(highlighter), isSaving])
|
|
452
454
|
|
|
453
455
|
const updateCurrentEditorContent = (newContent: string) => {
|
|
454
456
|
if (viewRef.current) {
|
|
@@ -207,19 +207,23 @@ export default function EditorNav({
|
|
|
207
207
|
<div className="flex items-center space-x-1">
|
|
208
208
|
{pkg && (
|
|
209
209
|
<>
|
|
210
|
-
<
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
className="text-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
210
|
+
<div className="flex items-center space-x-1 overflow-hidden">
|
|
211
|
+
<Link
|
|
212
|
+
className="text-blue-500 font-semibold hover:underline truncate"
|
|
213
|
+
href={`/${pkg.owner_github_username}`}
|
|
214
|
+
title={pkg.owner_github_username || ""}
|
|
215
|
+
>
|
|
216
|
+
{pkg.owner_github_username}
|
|
217
|
+
</Link>
|
|
218
|
+
<span className="px-0.5 text-gray-500">/</span>
|
|
219
|
+
<Link
|
|
220
|
+
className="text-blue-500 font-semibold hover:underline truncate"
|
|
221
|
+
href={`/${pkg.name}`}
|
|
222
|
+
title={pkg.unscoped_name}
|
|
223
|
+
>
|
|
224
|
+
{pkg.unscoped_name}
|
|
225
|
+
</Link>
|
|
226
|
+
</div>
|
|
223
227
|
{pkg.star_count !== undefined && (
|
|
224
228
|
<span className="ml-2 text-gray-500 text-xs flex items-center">
|
|
225
229
|
<Star className="w-3 h-3 mr-1" />
|
|
@@ -2,7 +2,6 @@ import type { Package } from "fake-snippets-api/lib/db/schema"
|
|
|
2
2
|
import { useMutation } from "react-query"
|
|
3
3
|
import { useAxios } from "./use-axios"
|
|
4
4
|
import { useGlobalStore } from "./use-global-store"
|
|
5
|
-
import { useUrlParams } from "./use-url-params"
|
|
6
5
|
|
|
7
6
|
export const useCreatePackageMutation = ({
|
|
8
7
|
onSuccess,
|
|
@@ -42,13 +41,7 @@ export const useCreatePackageMutation = ({
|
|
|
42
41
|
},
|
|
43
42
|
{
|
|
44
43
|
onSuccess: (pkg: Package) => {
|
|
45
|
-
const url = new URL(window.location.href)
|
|
46
|
-
url.searchParams.set("package_id", pkg.package_id)
|
|
47
|
-
url.searchParams.delete("template")
|
|
48
|
-
url.searchParams.delete("should_create_package")
|
|
49
|
-
window.history.pushState({}, "", url.toString())
|
|
50
44
|
onSuccess?.(pkg)
|
|
51
|
-
window.dispatchEvent(new Event("popstate"))
|
|
52
45
|
},
|
|
53
46
|
onError: (error: any) => {
|
|
54
47
|
console.error("Error creating package:", error)
|
|
@@ -31,17 +31,11 @@ export const useCurrentPackageId = (): {
|
|
|
31
31
|
error: errorPackageByName,
|
|
32
32
|
} = usePackageByName(packageName)
|
|
33
33
|
|
|
34
|
-
const {
|
|
35
|
-
data: packageById,
|
|
36
|
-
isLoading: isLoadingPackageById,
|
|
37
|
-
error: errorPackageById,
|
|
38
|
-
} = usePackageById(packageIdFromUrl)
|
|
39
|
-
|
|
40
34
|
const packageId = packageIdFromUrl ?? packageByName?.package_id ?? null
|
|
41
35
|
|
|
42
36
|
return {
|
|
43
37
|
packageId,
|
|
44
|
-
isLoading: isLoadingPackageByName
|
|
45
|
-
error: errorPackageByName
|
|
38
|
+
isLoading: isLoadingPackageByName,
|
|
39
|
+
error: errorPackageByName,
|
|
46
40
|
}
|
|
47
41
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { useParams } from "wouter"
|
|
2
|
+
import { useCurrentPackageId } from "./use-current-package-id"
|
|
3
|
+
import { useUrlParams } from "./use-url-params"
|
|
4
|
+
import { usePackageRelease } from "./use-package-release"
|
|
5
|
+
|
|
6
|
+
export const useCurrentPackageRelease = () => {
|
|
7
|
+
const { packageId } = useCurrentPackageId()
|
|
8
|
+
const urlParams = useUrlParams()
|
|
9
|
+
const { author, packageName } = useParams()
|
|
10
|
+
|
|
11
|
+
const version = urlParams.version
|
|
12
|
+
const releaseId = urlParams.package_release_id
|
|
13
|
+
|
|
14
|
+
let query: Parameters<typeof usePackageRelease>[0] | null = null
|
|
15
|
+
|
|
16
|
+
if (releaseId) {
|
|
17
|
+
query = { package_release_id: releaseId }
|
|
18
|
+
} else if (version && author && packageName) {
|
|
19
|
+
query = { package_name_with_version: `${author}/${packageName}@${version}` }
|
|
20
|
+
} else if (author && packageName) {
|
|
21
|
+
query = { package_name: `${author}/${packageName}`, is_latest: true }
|
|
22
|
+
} else if (packageId) {
|
|
23
|
+
query = { package_id: packageId, is_latest: true }
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const { data: packageRelease, ...rest } = usePackageRelease(query)
|
|
27
|
+
return { packageRelease, ...rest }
|
|
28
|
+
}
|
|
@@ -22,33 +22,21 @@ export function usePreviewImages({
|
|
|
22
22
|
id: "3d",
|
|
23
23
|
label: "3D View",
|
|
24
24
|
imageUrl: packageName
|
|
25
|
-
? `https://registry-api.tscircuit.com/packages/images/${packageName}/3d.png
|
|
26
|
-
{
|
|
27
|
-
fs_sha: fsMapHash ?? "",
|
|
28
|
-
},
|
|
29
|
-
).toString()}`
|
|
25
|
+
? `https://registry-api.tscircuit.com/packages/images/${packageName}/3d.png?fs_sha=${fsMapHash}`
|
|
30
26
|
: undefined,
|
|
31
27
|
},
|
|
32
28
|
{
|
|
33
29
|
id: "pcb",
|
|
34
30
|
label: "PCB View",
|
|
35
31
|
imageUrl: packageName
|
|
36
|
-
? `https://registry-api.tscircuit.com/packages/images/${packageName}/pcb.png
|
|
37
|
-
{
|
|
38
|
-
fs_sha: fsMapHash ?? "",
|
|
39
|
-
},
|
|
40
|
-
).toString()}`
|
|
32
|
+
? `https://registry-api.tscircuit.com/packages/images/${packageName}/pcb.png?fs_sha=${fsMapHash}`
|
|
41
33
|
: undefined,
|
|
42
34
|
},
|
|
43
35
|
{
|
|
44
36
|
id: "schematic",
|
|
45
37
|
label: "Schematic View",
|
|
46
38
|
imageUrl: packageName
|
|
47
|
-
? `https://registry-api.tscircuit.com/packages/images/${packageName}/schematic.png
|
|
48
|
-
{
|
|
49
|
-
fs_sha: fsMapHash ?? "",
|
|
50
|
-
},
|
|
51
|
-
).toString()}`
|
|
39
|
+
? `https://registry-api.tscircuit.com/packages/images/${packageName}/schematic.png?fs_sha=${fsMapHash}`
|
|
52
40
|
: undefined,
|
|
53
41
|
},
|
|
54
42
|
]
|
|
@@ -91,7 +91,31 @@ export function useFileManagement({
|
|
|
91
91
|
})
|
|
92
92
|
},
|
|
93
93
|
})
|
|
94
|
-
const createPackageMutation = useCreatePackageMutation(
|
|
94
|
+
const createPackageMutation = useCreatePackageMutation({
|
|
95
|
+
onSuccess: (newPackage) => {
|
|
96
|
+
createRelease(
|
|
97
|
+
{
|
|
98
|
+
package_name_with_version: `${newPackage.name}@latest`,
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
onSuccess: () => {
|
|
102
|
+
updatePackageFilesMutation.mutate({
|
|
103
|
+
package_name_with_version: `${newPackage.name}@latest`,
|
|
104
|
+
...newPackage,
|
|
105
|
+
})
|
|
106
|
+
const url = new URL(window.location.href)
|
|
107
|
+
url.searchParams.set("package_id", newPackage.package_id)
|
|
108
|
+
url.searchParams.delete("template")
|
|
109
|
+
url.searchParams.delete("should_create_package")
|
|
110
|
+
window.history.pushState({}, "", url.toString())
|
|
111
|
+
window.dispatchEvent(new Event("popstate"))
|
|
112
|
+
updateLastUpdated()
|
|
113
|
+
setInitialFiles([...localFiles])
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
)
|
|
117
|
+
},
|
|
118
|
+
})
|
|
95
119
|
|
|
96
120
|
useEffect(() => {
|
|
97
121
|
if (!currentPackage || isLoadingPackageFilesWithContent) {
|
|
@@ -204,29 +228,10 @@ export function useFileManagement({
|
|
|
204
228
|
return
|
|
205
229
|
}
|
|
206
230
|
|
|
207
|
-
|
|
231
|
+
await createPackageMutation.mutateAsync({
|
|
208
232
|
name: `${loggedInUser?.github_username}/${generateRandomPackageName()}`,
|
|
209
233
|
is_private: isPrivate,
|
|
210
234
|
})
|
|
211
|
-
|
|
212
|
-
if (newPackage) {
|
|
213
|
-
createRelease(
|
|
214
|
-
{
|
|
215
|
-
package_name_with_version: `${newPackage.name}@latest`,
|
|
216
|
-
},
|
|
217
|
-
{
|
|
218
|
-
onSuccess: () => {
|
|
219
|
-
updatePackageFilesMutation.mutate({
|
|
220
|
-
package_name_with_version: `${newPackage.name}@latest`,
|
|
221
|
-
...newPackage,
|
|
222
|
-
})
|
|
223
|
-
updateLastUpdated()
|
|
224
|
-
setInitialFiles([...localFiles])
|
|
225
|
-
},
|
|
226
|
-
},
|
|
227
|
-
)
|
|
228
|
-
}
|
|
229
|
-
updateLastUpdated()
|
|
230
235
|
}
|
|
231
236
|
|
|
232
237
|
const saveFiles = () => {
|
|
@@ -1,8 +1,17 @@
|
|
|
1
|
+
import { findTargetFile } from "./findTargetFile"
|
|
2
|
+
|
|
1
3
|
export const checkIfManualEditsImported = (
|
|
2
4
|
files: Record<string, string>,
|
|
3
5
|
file: string = "index.tsx",
|
|
4
6
|
) => {
|
|
5
7
|
if (!files[file]) return false
|
|
8
|
+
const targetFile = findTargetFile(
|
|
9
|
+
Object.keys(files).map((f) => ({ path: f, content: files[f] })),
|
|
10
|
+
null,
|
|
11
|
+
)
|
|
12
|
+
if (targetFile && file !== targetFile.path) {
|
|
13
|
+
return false
|
|
14
|
+
}
|
|
6
15
|
if (!file.endsWith(".tsx") && !file.endsWith(".ts")) return false
|
|
7
16
|
const importRegex =
|
|
8
17
|
/import\s+(?:\*\s+as\s+)?([a-zA-Z_$][\w$]*)\s+from\s+["'](?:\.\/)?manual-edits\.json["'];?/
|
package/src/pages/editor.tsx
CHANGED
|
@@ -4,14 +4,10 @@ import Header from "@/components/Header"
|
|
|
4
4
|
import { Helmet } from "react-helmet-async"
|
|
5
5
|
import { useCurrentPackageId } from "@/hooks/use-current-package-id"
|
|
6
6
|
import { usePackage } from "@/hooks/use-package"
|
|
7
|
-
import { useGetFsMapHashForPackage } from "@/hooks/use-get-fsmap-hash-for-package"
|
|
8
7
|
|
|
9
8
|
export const EditorPage = () => {
|
|
10
9
|
const { packageId } = useCurrentPackageId()
|
|
11
10
|
const { data: pkg, isLoading, error } = usePackage(packageId)
|
|
12
|
-
const fsMapHash = useGetFsMapHashForPackage(
|
|
13
|
-
pkg?.latest_package_release_id ?? "",
|
|
14
|
-
)
|
|
15
11
|
|
|
16
12
|
return (
|
|
17
13
|
<div className="overflow-x-hidden">
|
|
@@ -27,16 +23,12 @@ export const EditorPage = () => {
|
|
|
27
23
|
/>
|
|
28
24
|
<meta
|
|
29
25
|
property="og:image"
|
|
30
|
-
content={`https://registry-api.tscircuit.com/packages/images/${pkg.owner_github_username}/${pkg.unscoped_name}/pcb.png
|
|
31
|
-
{
|
|
32
|
-
fs_sha: fsMapHash ?? "",
|
|
33
|
-
},
|
|
34
|
-
).toString()}`}
|
|
26
|
+
content={`https://registry-api.tscircuit.com/packages/images/${pkg.owner_github_username}/${pkg.unscoped_name}/pcb.png?fs_sha=${pkg.latest_package_release_fs_sha}`}
|
|
35
27
|
/>
|
|
36
28
|
<meta name="twitter:card" content="summary_large_image" />
|
|
37
29
|
<meta
|
|
38
30
|
name="twitter:image"
|
|
39
|
-
content={`https://registry-api.tscircuit.com/packages/images/${pkg.owner_github_username}/${pkg.unscoped_name}/pcb.png`}
|
|
31
|
+
content={`https://registry-api.tscircuit.com/packages/images/${pkg.owner_github_username}/${pkg.unscoped_name}/pcb.png?fs_sha=${pkg.latest_package_release_fs_sha}`}
|
|
40
32
|
/>
|
|
41
33
|
</>
|
|
42
34
|
)}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { CodeAndPreview } from "@/components/package-port/CodeAndPreview"
|
|
2
|
+
import Footer from "@/components/Footer"
|
|
3
|
+
import Header from "@/components/Header"
|
|
4
|
+
import { usePackage } from "@/hooks/use-package"
|
|
5
|
+
import { Helmet } from "react-helmet-async"
|
|
6
|
+
import { useCurrentPackageId } from "@/hooks/use-current-package-id"
|
|
7
|
+
import { NotFound } from "@/components/NotFound"
|
|
8
|
+
import { ErrorOutline } from "@/components/ErrorOutline"
|
|
9
|
+
import { PackageBuildDetailsPage } from "@/components/PackageBuildsPage/PackageBuildDetailsPage"
|
|
10
|
+
|
|
11
|
+
export const EditorPage = () => {
|
|
12
|
+
const { packageId } = useCurrentPackageId()
|
|
13
|
+
const { data: pkg, error } = usePackage(packageId)
|
|
14
|
+
const uuid4RegExp = new RegExp(
|
|
15
|
+
/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$/,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<div className="overflow-x-hidden">
|
|
20
|
+
<Helmet>
|
|
21
|
+
<title>{pkg ? `${pkg.name} Package Builds` : "Package Builds"}</title>
|
|
22
|
+
{pkg && (
|
|
23
|
+
<>
|
|
24
|
+
<meta property="og:title" content={`${pkg.name} Package Builds`} />
|
|
25
|
+
</>
|
|
26
|
+
)}
|
|
27
|
+
</Helmet>
|
|
28
|
+
<Header />
|
|
29
|
+
<PackageBuildDetailsPage />
|
|
30
|
+
<Footer />
|
|
31
|
+
</div>
|
|
32
|
+
)
|
|
33
|
+
}
|
|
@@ -6,14 +6,10 @@ import { Helmet } from "react-helmet-async"
|
|
|
6
6
|
import { useCurrentPackageId } from "@/hooks/use-current-package-id"
|
|
7
7
|
import { NotFound } from "@/components/NotFound"
|
|
8
8
|
import { ErrorOutline } from "@/components/ErrorOutline"
|
|
9
|
-
import { useGetFsMapHashForPackage } from "@/hooks/use-get-fsmap-hash-for-package"
|
|
10
9
|
|
|
11
10
|
export const EditorPage = () => {
|
|
12
11
|
const { packageId } = useCurrentPackageId()
|
|
13
12
|
const { data: pkg, error } = usePackage(packageId)
|
|
14
|
-
const fsMapHash = useGetFsMapHashForPackage(
|
|
15
|
-
pkg?.latest_package_release_id ?? "",
|
|
16
|
-
)
|
|
17
13
|
const uuid4RegExp = new RegExp(
|
|
18
14
|
/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$/,
|
|
19
15
|
)
|
|
@@ -30,20 +26,12 @@ export const EditorPage = () => {
|
|
|
30
26
|
/>
|
|
31
27
|
<meta
|
|
32
28
|
property="og:image"
|
|
33
|
-
content={`https://registry-api.tscircuit.com/packages/images/${pkg.owner_github_username}/${pkg.unscoped_name}/pcb.png
|
|
34
|
-
{
|
|
35
|
-
fs_sha: fsMapHash ?? "",
|
|
36
|
-
},
|
|
37
|
-
).toString()}`}
|
|
29
|
+
content={`https://registry-api.tscircuit.com/packages/images/${pkg.owner_github_username}/${pkg.unscoped_name}/pcb.png?fs_sha=${pkg.latest_package_release_fs_sha}`}
|
|
38
30
|
/>
|
|
39
31
|
<meta name="twitter:card" content="summary_large_image" />
|
|
40
32
|
<meta
|
|
41
33
|
name="twitter:image"
|
|
42
|
-
content={`https://registry-api.tscircuit.com/packages/images/${pkg.owner_github_username}/${pkg.unscoped_name}/pcb.png
|
|
43
|
-
{
|
|
44
|
-
fs_sha: fsMapHash ?? "",
|
|
45
|
-
},
|
|
46
|
-
).toString()}`}
|
|
34
|
+
content={`https://registry-api.tscircuit.com/packages/images/${pkg.owner_github_username}/${pkg.unscoped_name}/pcb.png?fs_sha=${pkg.latest_package_release_fs_sha}`}
|
|
47
35
|
/>
|
|
48
36
|
</>
|
|
49
37
|
)}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { usePackageFiles } from "@/hooks/use-package-files"
|
|
2
|
-
import md5 from "md5"
|
|
3
|
-
|
|
4
|
-
export const useGetFsMapHashForPackage = (packageReleaseId: string) => {
|
|
5
|
-
const { data: pkgFilesList } = usePackageFiles(packageReleaseId)
|
|
6
|
-
|
|
7
|
-
if (!pkgFilesList) {
|
|
8
|
-
console.error(
|
|
9
|
-
`No package files found for package release ${packageReleaseId}`,
|
|
10
|
-
)
|
|
11
|
-
return null
|
|
12
|
-
}
|
|
13
|
-
const fsMap = new Map<string, string>()
|
|
14
|
-
for (const file of pkgFilesList) {
|
|
15
|
-
fsMap.set(file.file_path, file.content_text ?? "")
|
|
16
|
-
}
|
|
17
|
-
const fsMapHash = md5(JSON.stringify(fsMap))
|
|
18
|
-
return `md5-${fsMapHash}`
|
|
19
|
-
}
|