@tscircuit/fake-snippets 0.0.65 → 0.0.67
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/CONTRIBUTING.md +2 -2
- package/README.md +2 -2
- package/bun-tests/fake-snippets-api/fixtures/get-circuit-json.ts +5 -143
- package/bun-tests/fake-snippets-api/fixtures/get-test-server.ts +1 -4
- package/bun-tests/fake-snippets-api/fixtures/start-server.ts +7 -3
- package/bun-tests/fake-snippets-api/routes/order_quotes/create.test.ts +20 -56
- package/bun-tests/fake-snippets-api/routes/package_files/create_or_update.test.ts +2 -2
- package/bun-tests/fake-snippets-api/routes/package_releases/update.test.ts +1 -1
- package/bun-tests/fake-snippets-api/routes/packages/images.test.ts +1 -16
- package/bun.lock +42 -31
- package/dist/bundle.js +34 -41
- package/fake-snippets-api/routes/api/order_quotes/create.ts +30 -37
- package/fake-snippets-api/routes/api/order_quotes/get.ts +5 -8
- package/fake-snippets-api/routes/api/packages/images/[owner_github_username]/[unscoped_name]/[view_format].ts +3 -3
- package/package.json +7 -5
- package/src/App.tsx +0 -7
- package/src/ContextProviders.tsx +2 -0
- package/src/components/DownloadButtonAndMenu.tsx +1 -4
- package/src/components/ErrorTabContent.tsx +1 -1
- package/src/components/Footer.tsx +5 -2
- package/src/components/HeaderLogin.tsx +37 -54
- package/src/components/ImageWithFallback.tsx +37 -0
- package/src/components/JLCPCBImportDialog.tsx +43 -24
- package/src/components/PackageCard.tsx +12 -3
- package/src/components/{SnippetLink.tsx → PackageLink.tsx} +8 -16
- package/src/components/PackageSearchResults.tsx +87 -0
- package/src/components/PackagesList.tsx +3 -3
- package/src/components/PageSearchComponent.tsx +9 -9
- package/src/components/ShippingInformationForm.tsx +1 -1
- package/src/components/TrendingPackagesCarousel.tsx +43 -23
- package/src/components/ViewPackagePage/components/ShikiCodeViewer.tsx +5 -28
- package/src/components/ViewPackagePage/components/main-content-header.tsx +10 -22
- package/src/components/ViewPackagePage/components/mobile-sidebar.tsx +25 -14
- package/src/components/ViewPackagePage/components/package-header.tsx +9 -4
- package/src/components/ViewPackagePage/components/preview-image-squares.tsx +6 -1
- package/src/components/ViewPackagePage/components/repo-page-content.tsx +4 -4
- package/src/components/ViewPackagePage/components/sidebar.tsx +2 -14
- package/src/components/ViewSnippetSidebar.tsx +1 -1
- package/src/components/package-port/CodeEditor.tsx +13 -10
- package/src/components/package-port/CodeEditorHeader.tsx +1 -1
- package/src/components/package-port/EditorNav.tsx +2 -2
- package/src/hooks/use-get-fsmap-hash-for-package.ts +19 -0
- package/src/hooks/use-global-store.ts +1 -0
- package/src/hooks/use-preview-images.ts +20 -4
- package/src/hooks/use-shiki-highlighter.ts +13 -6
- package/src/hooks/use-toast.tsx +1 -1
- package/src/lib/download-fns/download-gltf.ts +3 -10
- package/src/lib/handleManualEditsImport.tsx +1 -1
- package/src/lib/types.ts +4 -2
- package/src/pages/dashboard.tsx +3 -4
- package/src/pages/editor.tsx +20 -14
- package/src/pages/latest.tsx +25 -26
- package/src/pages/package-editor.tsx +14 -2
- package/src/pages/search.tsx +120 -19
- package/src/pages/trending.tsx +14 -59
- package/src/pages/user-profile.tsx +13 -8
- package/bun-tests/fake-snippets-api/routes/snippets/add_star.test.ts +0 -84
- package/bun-tests/fake-snippets-api/routes/snippets/create.test.ts +0 -53
- package/bun-tests/fake-snippets-api/routes/snippets/delete.test.ts +0 -82
- package/bun-tests/fake-snippets-api/routes/snippets/download.test.ts +0 -90
- package/bun-tests/fake-snippets-api/routes/snippets/generate_from_jlcpcb.test.ts +0 -16
- package/bun-tests/fake-snippets-api/routes/snippets/get.test.ts +0 -163
- package/bun-tests/fake-snippets-api/routes/snippets/get_image.test.ts +0 -117
- package/bun-tests/fake-snippets-api/routes/snippets/images.test.ts +0 -114
- package/bun-tests/fake-snippets-api/routes/snippets/list.test.ts +0 -169
- package/bun-tests/fake-snippets-api/routes/snippets/list_newest.test.ts +0 -50
- package/bun-tests/fake-snippets-api/routes/snippets/list_trending.test.ts +0 -72
- package/bun-tests/fake-snippets-api/routes/snippets/remove_star.test.ts +0 -80
- package/bun-tests/fake-snippets-api/routes/snippets/search.test.ts +0 -75
- package/bun-tests/fake-snippets-api/routes/snippets/star-count.test.ts +0 -51
- package/bun-tests/fake-snippets-api/routes/snippets/update.test.ts +0 -175
- package/src/components/AiChatInterface.tsx +0 -229
- package/src/components/CodeAndPreview.tsx +0 -289
- package/src/components/CodeEditor.tsx +0 -539
- package/src/components/CodeEditorHeader.tsx +0 -135
- package/src/components/EditorNav.tsx +0 -502
- package/src/components/PreviewContent.tsx +0 -372
- package/src/components/SnippetCard.tsx +0 -159
- package/src/components/SnippetList.tsx +0 -71
- package/src/hooks/use-compiled-tsx.ts +0 -37
- package/src/hooks/use-run-tsx/construct-circuit.tsx +0 -62
- package/src/hooks/use-run-tsx/index.tsx +0 -256
- package/src/hooks/use-save-snippet.ts +0 -66
- package/src/hooks/use-typecheck.ts +0 -54
- package/src/lib/utils/getSyntaxError.ts +0 -13
- package/src/pages/ai.tsx +0 -92
- package/src/pages/view-snippet.tsx +0 -166
package/src/pages/trending.tsx
CHANGED
|
@@ -14,17 +14,14 @@ import {
|
|
|
14
14
|
SelectTrigger,
|
|
15
15
|
SelectValue,
|
|
16
16
|
} from "@/components/ui/select"
|
|
17
|
-
import { SnippetCard } from "@/components/SnippetCard"
|
|
18
|
-
import { PackageCardSkeleton } from "@/components/PackageCardSkeleton"
|
|
19
17
|
import { Package } from "fake-snippets-api/lib/db/schema"
|
|
20
|
-
import
|
|
18
|
+
import PackageSearchResults from "@/components/PackageSearchResults"
|
|
21
19
|
|
|
22
20
|
const TrendingPage: React.FC = () => {
|
|
23
21
|
const axios = useAxios()
|
|
24
22
|
const apiBaseUrl = useSnippetsBaseApiUrl()
|
|
25
23
|
const [searchParams, setSearchParams] = useSearchParams()
|
|
26
24
|
|
|
27
|
-
// Initialize state from URL params or defaults
|
|
28
25
|
const [searchQuery, setSearchQuery] = useState(searchParams.get("q") || "")
|
|
29
26
|
const [category, setCategory] = useState(
|
|
30
27
|
searchParams.get("category") || "all",
|
|
@@ -34,7 +31,6 @@ const TrendingPage: React.FC = () => {
|
|
|
34
31
|
)
|
|
35
32
|
const [sortBy, setSortBy] = useState(searchParams.get("sort") || "stars")
|
|
36
33
|
|
|
37
|
-
// Update URL params when filters change
|
|
38
34
|
useEffect(() => {
|
|
39
35
|
const params = new URLSearchParams()
|
|
40
36
|
if (searchQuery) params.set("q", searchQuery)
|
|
@@ -48,7 +44,6 @@ const TrendingPage: React.FC = () => {
|
|
|
48
44
|
data: packages,
|
|
49
45
|
isLoading,
|
|
50
46
|
error,
|
|
51
|
-
refetch,
|
|
52
47
|
} = useQuery<Package[]>(
|
|
53
48
|
["trendingPackages", category, time_period],
|
|
54
49
|
async () => {
|
|
@@ -71,7 +66,6 @@ const TrendingPage: React.FC = () => {
|
|
|
71
66
|
if (!searchQuery) return true
|
|
72
67
|
|
|
73
68
|
const query = searchQuery.toLowerCase().trim()
|
|
74
|
-
|
|
75
69
|
const searchableFields = [
|
|
76
70
|
pkg.unscoped_name.toLowerCase(),
|
|
77
71
|
(pkg.owner_github_username || "").toLowerCase(),
|
|
@@ -176,58 +170,19 @@ const TrendingPage: React.FC = () => {
|
|
|
176
170
|
</Select>
|
|
177
171
|
</div>
|
|
178
172
|
</div>
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
<div>
|
|
193
|
-
<h3 className="text-lg font-semibold mb-2">
|
|
194
|
-
Error Loading packages
|
|
195
|
-
</h3>
|
|
196
|
-
<p className="text-red-600">
|
|
197
|
-
We couldn't load the trending packages. Please try again
|
|
198
|
-
later.
|
|
199
|
-
</p>
|
|
200
|
-
</div>
|
|
201
|
-
</div>
|
|
202
|
-
</div>
|
|
203
|
-
) : filteredPackages?.length === 0 ? (
|
|
204
|
-
<div className="text-center py-12 px-4">
|
|
205
|
-
<div className="bg-slate-50 inline-flex rounded-full p-4 mb-4">
|
|
206
|
-
<Search className="w-8 h-8 text-slate-400" />
|
|
207
|
-
</div>
|
|
208
|
-
<h3 className="text-xl font-medium text-slate-900 mb-2">
|
|
209
|
-
No Matching Packages
|
|
210
|
-
</h3>
|
|
211
|
-
<p className="text-slate-500 max-w-md mx-auto mb-6">
|
|
212
|
-
{searchQuery
|
|
213
|
-
? `No packages match your search for "${searchQuery}".`
|
|
214
|
-
: category !== "all"
|
|
215
|
-
? `No ${category} packages found in the trending list.`
|
|
216
|
-
: "There are no trending packages at the moment."}
|
|
217
|
-
</p>
|
|
218
|
-
</div>
|
|
219
|
-
) : (
|
|
220
|
-
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
221
|
-
{filteredPackages?.map((pkg) => (
|
|
222
|
-
<PackageCard
|
|
223
|
-
key={pkg.package_id}
|
|
224
|
-
pkg={pkg}
|
|
225
|
-
baseUrl={apiBaseUrl}
|
|
226
|
-
showOwner={true}
|
|
227
|
-
/>
|
|
228
|
-
))}
|
|
229
|
-
</div>
|
|
230
|
-
)}
|
|
173
|
+
<PackageSearchResults
|
|
174
|
+
isLoading={isLoading}
|
|
175
|
+
error={error}
|
|
176
|
+
filteredPackages={filteredPackages}
|
|
177
|
+
apiBaseUrl={apiBaseUrl}
|
|
178
|
+
emptyStateMessage={
|
|
179
|
+
searchQuery
|
|
180
|
+
? `No packages match your search for "${searchQuery}".`
|
|
181
|
+
: category !== "all"
|
|
182
|
+
? `No ${category} packages found in the trending list.`
|
|
183
|
+
: "There are no trending packages at the moment."
|
|
184
|
+
}
|
|
185
|
+
/>
|
|
231
186
|
</main>
|
|
232
187
|
<Footer />
|
|
233
188
|
</div>
|
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
SelectValue,
|
|
24
24
|
} from "@/components/ui/select"
|
|
25
25
|
import { Box, Star } from "lucide-react"
|
|
26
|
+
import { PackageCardSkeleton } from "@/components/PackageCardSkeleton"
|
|
26
27
|
|
|
27
28
|
export const UserProfilePage = () => {
|
|
28
29
|
const { username } = useParams()
|
|
@@ -159,10 +160,10 @@ export const UserProfilePage = () => {
|
|
|
159
160
|
</Select>
|
|
160
161
|
</div>
|
|
161
162
|
{isLoading ? (
|
|
162
|
-
<div>
|
|
163
|
-
{
|
|
164
|
-
|
|
165
|
-
|
|
163
|
+
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
164
|
+
{[...Array(6)].map((_, i) => (
|
|
165
|
+
<PackageCardSkeleton key={i} />
|
|
166
|
+
))}
|
|
166
167
|
</div>
|
|
167
168
|
) : (
|
|
168
169
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
@@ -184,16 +185,20 @@ export const UserProfilePage = () => {
|
|
|
184
185
|
<div className="flex flex-col items-center py-12 text-gray-500">
|
|
185
186
|
{activeTab === "starred" ? (
|
|
186
187
|
<>
|
|
187
|
-
<Star />
|
|
188
|
+
<Star className="mb-2" size={24} />
|
|
188
189
|
<span className="text-lg font-medium">
|
|
189
|
-
|
|
190
|
+
{searchQuery.trim()
|
|
191
|
+
? `No starred packages matching '${searchQuery.trim()}'`
|
|
192
|
+
: "No starred packages"}
|
|
190
193
|
</span>
|
|
191
194
|
</>
|
|
192
195
|
) : (
|
|
193
196
|
<>
|
|
194
|
-
<Box />
|
|
197
|
+
<Box className="mb-2" size={24} />
|
|
195
198
|
<span className="text-lg font-medium">
|
|
196
|
-
|
|
199
|
+
{searchQuery.trim()
|
|
200
|
+
? `No packages matching '${searchQuery.trim()}'`
|
|
201
|
+
: "No packages available"}
|
|
197
202
|
</span>
|
|
198
203
|
</>
|
|
199
204
|
)}
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import { getTestServer } from "bun-tests/fake-snippets-api/fixtures/get-test-server"
|
|
2
|
-
import { expect, test } from "bun:test"
|
|
3
|
-
|
|
4
|
-
test("add star to snippet", async () => {
|
|
5
|
-
const { axios } = await getTestServer()
|
|
6
|
-
|
|
7
|
-
// Create a test snippet using the create endpoint
|
|
8
|
-
const newSnippetData = {
|
|
9
|
-
code: "Test Content",
|
|
10
|
-
snippet_type: "package",
|
|
11
|
-
description: "Test Description",
|
|
12
|
-
}
|
|
13
|
-
const createResponse = await axios.post(
|
|
14
|
-
"/api/snippets/create",
|
|
15
|
-
newSnippetData,
|
|
16
|
-
)
|
|
17
|
-
expect(createResponse.status).toBe(200)
|
|
18
|
-
const createdSnippet = createResponse.data.snippet
|
|
19
|
-
|
|
20
|
-
// Star the snippet
|
|
21
|
-
const response = await axios.post("/api/snippets/add_star", {
|
|
22
|
-
snippet_id: createdSnippet.snippet_id,
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
expect(response.status).toBe(200)
|
|
26
|
-
expect(response.data.ok).toBe(true)
|
|
27
|
-
|
|
28
|
-
// Verify star was added by checking the snippet again
|
|
29
|
-
const getResponse = await axios.get("/api/snippets/get", {
|
|
30
|
-
params: { snippet_id: createdSnippet.snippet_id },
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
expect(getResponse.status).toBe(200)
|
|
34
|
-
expect(getResponse.data.snippet.is_starred).toBe(true)
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
test("add star to non-existent snippet", async () => {
|
|
38
|
-
const { axios } = await getTestServer()
|
|
39
|
-
|
|
40
|
-
try {
|
|
41
|
-
await axios.post("/api/snippets/add_star", {
|
|
42
|
-
snippet_id: "non-existent-id",
|
|
43
|
-
})
|
|
44
|
-
expect(true).toBe(false) // Should not reach here
|
|
45
|
-
} catch (error: any) {
|
|
46
|
-
expect(error.status).toBe(404)
|
|
47
|
-
expect(error.data.error.message).toBe("Snippet not found")
|
|
48
|
-
}
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
test("add star to already starred snippet", async () => {
|
|
52
|
-
const { axios } = await getTestServer()
|
|
53
|
-
|
|
54
|
-
// Create a test snippet using the create endpoint
|
|
55
|
-
const newSnippetData = {
|
|
56
|
-
code: "Test Content",
|
|
57
|
-
snippet_type: "package",
|
|
58
|
-
description: "Test Description",
|
|
59
|
-
}
|
|
60
|
-
const createResponse = await axios.post(
|
|
61
|
-
"/api/snippets/create",
|
|
62
|
-
newSnippetData,
|
|
63
|
-
)
|
|
64
|
-
expect(createResponse.status).toBe(200)
|
|
65
|
-
const createdSnippet = createResponse.data.snippet
|
|
66
|
-
|
|
67
|
-
// Star the snippet first time
|
|
68
|
-
await axios.post("/api/snippets/add_star", {
|
|
69
|
-
snippet_id: createdSnippet.snippet_id,
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
// Try to star again
|
|
73
|
-
try {
|
|
74
|
-
await axios.post("/api/snippets/add_star", {
|
|
75
|
-
snippet_id: createdSnippet.snippet_id,
|
|
76
|
-
})
|
|
77
|
-
expect(true).toBe(false) // Should not reach here
|
|
78
|
-
} catch (error: any) {
|
|
79
|
-
expect(error.status).toBe(400)
|
|
80
|
-
expect(error.data.error.message).toBe(
|
|
81
|
-
"You have already starred this snippet",
|
|
82
|
-
)
|
|
83
|
-
}
|
|
84
|
-
})
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { getTestServer } from "bun-tests/fake-snippets-api/fixtures/get-test-server"
|
|
2
|
-
import { expect, test } from "bun:test"
|
|
3
|
-
|
|
4
|
-
test("create snippet", async () => {
|
|
5
|
-
const { axios } = await getTestServer()
|
|
6
|
-
|
|
7
|
-
const response = await axios.post("/api/snippets/create", {
|
|
8
|
-
unscoped_name: "TestSnippet",
|
|
9
|
-
code: "Test Content",
|
|
10
|
-
snippet_type: "package",
|
|
11
|
-
description: "Test Description",
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
expect(response.status).toBe(200)
|
|
15
|
-
expect(response.data.snippet.unscoped_name).toBe("TestSnippet")
|
|
16
|
-
expect(response.data.snippet.owner_name).toBe("testuser")
|
|
17
|
-
expect(response.data.snippet.code).toBe("Test Content")
|
|
18
|
-
expect(response.data.snippet.snippet_type).toBe("package")
|
|
19
|
-
expect(response.data.snippet.description).toBe("Test Description")
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
test("create snippet and call package get to verify it exists", async () => {
|
|
23
|
-
const { axios, db } = await getTestServer()
|
|
24
|
-
|
|
25
|
-
const response = await axios.post("/api/snippets/create", {
|
|
26
|
-
unscoped_name: "example-package",
|
|
27
|
-
code: "console.log('Hello, world!');",
|
|
28
|
-
snippet_type: "package",
|
|
29
|
-
description: "Test Description",
|
|
30
|
-
})
|
|
31
|
-
const packageResponse = await axios.get(`/api/packages/get`, {
|
|
32
|
-
params: {
|
|
33
|
-
package_id: response.data.snippet.snippet_id,
|
|
34
|
-
},
|
|
35
|
-
})
|
|
36
|
-
expect(packageResponse.status).toBe(200)
|
|
37
|
-
expect(packageResponse.data.package.unscoped_name).toBe("example-package")
|
|
38
|
-
expect(packageResponse.data.package.owner_github_username).toBe("testuser")
|
|
39
|
-
expect(packageResponse.data.package.description).toBe("Test Description")
|
|
40
|
-
|
|
41
|
-
// Add package file verification
|
|
42
|
-
const packageFileResponse = await axios.post(`/api/package_files/get`, {
|
|
43
|
-
package_release_id: packageResponse.data.package.latest_package_release_id,
|
|
44
|
-
file_path: "index.tsx",
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
expect(packageFileResponse.status).toBe(200)
|
|
48
|
-
expect(packageFileResponse.data.ok).toBe(true)
|
|
49
|
-
expect(packageFileResponse.data.package_file).toBeDefined()
|
|
50
|
-
expect(packageFileResponse.data.package_file.content_text).toBe(
|
|
51
|
-
"console.log('Hello, world!');",
|
|
52
|
-
)
|
|
53
|
-
})
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { getTestServer } from "bun-tests/fake-snippets-api/fixtures/get-test-server"
|
|
2
|
-
import { test, expect } from "bun:test"
|
|
3
|
-
|
|
4
|
-
test("delete snippet", async () => {
|
|
5
|
-
const { axios, db } = await getTestServer()
|
|
6
|
-
|
|
7
|
-
// Add a test snippet
|
|
8
|
-
const snippet = {
|
|
9
|
-
unscoped_name: "TestSnippet",
|
|
10
|
-
owner_name: "testuser",
|
|
11
|
-
code: "Test Content",
|
|
12
|
-
created_at: "2023-01-01T00:00:00Z",
|
|
13
|
-
updated_at: "2023-01-01T00:00:00Z",
|
|
14
|
-
name: "testuser/TestSnippet",
|
|
15
|
-
snippet_type: "package",
|
|
16
|
-
description: "Test Description",
|
|
17
|
-
}
|
|
18
|
-
const addedSnippet: any = db.addSnippet(snippet as any)
|
|
19
|
-
|
|
20
|
-
// Delete the snippet
|
|
21
|
-
const response = await axios.post("/api/snippets/delete", {
|
|
22
|
-
snippet_id: addedSnippet.snippet_id,
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
expect(response.status).toBe(200)
|
|
26
|
-
expect(response.data.ok).toBe(true)
|
|
27
|
-
|
|
28
|
-
// Verify the snippet was deleted from the database
|
|
29
|
-
const deletedSnippet = db.getSnippetById(addedSnippet.snippet_id)
|
|
30
|
-
expect(deletedSnippet).toBeUndefined()
|
|
31
|
-
|
|
32
|
-
// List all the snippets and verify the deleted snippet is not in the list
|
|
33
|
-
const listResponse = await axios.get("/api/snippets/list")
|
|
34
|
-
|
|
35
|
-
expect(listResponse.status).toBe(200)
|
|
36
|
-
expect(listResponse.data.snippets).toHaveLength(0)
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
test("delete non-existent snippet", async () => {
|
|
40
|
-
const { axios } = await getTestServer()
|
|
41
|
-
|
|
42
|
-
try {
|
|
43
|
-
await axios.post("/api/snippets/delete", {
|
|
44
|
-
snippet_id: "non-existent-id",
|
|
45
|
-
})
|
|
46
|
-
// If the request doesn't throw an error, fail the test
|
|
47
|
-
expect(true).toBe(false)
|
|
48
|
-
} catch (error: any) {
|
|
49
|
-
expect(error.status).toBe(404)
|
|
50
|
-
expect(error.data.error.message).toBe("Snippet not found")
|
|
51
|
-
}
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
test("delete snippet without permission", async () => {
|
|
55
|
-
const { axios, db } = await getTestServer()
|
|
56
|
-
|
|
57
|
-
// Add a test snippet with a different owner
|
|
58
|
-
const snippet = {
|
|
59
|
-
unscoped_name: "TestSnippet",
|
|
60
|
-
owner_name: "otheruser",
|
|
61
|
-
code: "Test Content",
|
|
62
|
-
created_at: "2023-01-01T00:00:00Z",
|
|
63
|
-
updated_at: "2023-01-01T00:00:00Z",
|
|
64
|
-
name: "otheruser/TestSnippet",
|
|
65
|
-
snippet_type: "package",
|
|
66
|
-
description: "Test Description",
|
|
67
|
-
}
|
|
68
|
-
const addedSnippet: any = db.addSnippet(snippet as any)
|
|
69
|
-
|
|
70
|
-
try {
|
|
71
|
-
await axios.post("/api/snippets/delete", {
|
|
72
|
-
snippet_id: addedSnippet.snippet_id,
|
|
73
|
-
})
|
|
74
|
-
// If the request doesn't throw an error, fail the test
|
|
75
|
-
expect(true).toBe(false)
|
|
76
|
-
} catch (error: any) {
|
|
77
|
-
expect(error.status).toBe(403)
|
|
78
|
-
expect(error.data.error.message).toBe(
|
|
79
|
-
"You don't have permission to delete this snippet",
|
|
80
|
-
)
|
|
81
|
-
}
|
|
82
|
-
})
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { getTestServer } from "bun-tests/fake-snippets-api/fixtures/get-test-server"
|
|
2
|
-
import { test, expect } from "bun:test"
|
|
3
|
-
|
|
4
|
-
test("download snippet files and directory listing", async () => {
|
|
5
|
-
const { axios, db } = await getTestServer()
|
|
6
|
-
|
|
7
|
-
// Add a test snippet
|
|
8
|
-
const snippet = {
|
|
9
|
-
unscoped_name: "test-package",
|
|
10
|
-
owner_name: "testuser",
|
|
11
|
-
code: "export const TestComponent = () => <div>Test</div>",
|
|
12
|
-
dts: "export declare const TestComponent: () => JSX.Element",
|
|
13
|
-
created_at: "2023-01-01T00:00:00Z",
|
|
14
|
-
updated_at: "2023-01-01T00:00:00Z",
|
|
15
|
-
name: "testuser/test-package",
|
|
16
|
-
snippet_type: "package",
|
|
17
|
-
description: "Test package",
|
|
18
|
-
}
|
|
19
|
-
db.addSnippet(snippet as any)
|
|
20
|
-
|
|
21
|
-
// Test downloading index.ts
|
|
22
|
-
const indexResponse = await axios.get("/api/snippets/download", {
|
|
23
|
-
params: { jsdelivr_path: "testuser/test-package@1.0.0/index.ts" },
|
|
24
|
-
})
|
|
25
|
-
expect(indexResponse.status).toBe(200)
|
|
26
|
-
expect(indexResponse.data).toBe(snippet.code)
|
|
27
|
-
|
|
28
|
-
// Test downloading index.d.ts
|
|
29
|
-
const dtsResponse = await axios.get("/api/snippets/download", {
|
|
30
|
-
params: { jsdelivr_path: "testuser/test-package@1.0.0/index.d.ts" },
|
|
31
|
-
})
|
|
32
|
-
expect(dtsResponse.status).toBe(200)
|
|
33
|
-
expect(dtsResponse.data).toBe(snippet.dts)
|
|
34
|
-
|
|
35
|
-
// Test downloading package.json
|
|
36
|
-
const packageJsonResponse = await axios.get("/api/snippets/download", {
|
|
37
|
-
params: { jsdelivr_path: "testuser/test-package@1.0.0/package.json" },
|
|
38
|
-
})
|
|
39
|
-
expect(packageJsonResponse.status).toBe(200)
|
|
40
|
-
const packageJson = packageJsonResponse.data
|
|
41
|
-
expect(packageJson).toEqual({
|
|
42
|
-
name: "@tsci/testuser.test-package",
|
|
43
|
-
version: "1.0.0",
|
|
44
|
-
main: "index.ts",
|
|
45
|
-
types: "index.d.ts",
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
// Test downloading root (directory listing)
|
|
49
|
-
const rootResponse = await axios.get("/api/snippets/download", {
|
|
50
|
-
params: { jsdelivr_path: "testuser/test-package@1.0.0" },
|
|
51
|
-
})
|
|
52
|
-
expect(rootResponse.status).toBe(200)
|
|
53
|
-
const rootData = rootResponse.data
|
|
54
|
-
expect(rootData.tags).toBeDefined()
|
|
55
|
-
expect(rootData.versions).toBeDefined()
|
|
56
|
-
|
|
57
|
-
// Test downloading flat directory listing
|
|
58
|
-
const flatResponse = await axios.get("/api/snippets/download", {
|
|
59
|
-
params: { jsdelivr_path: "testuser/test-package@1.0.0/flat" },
|
|
60
|
-
})
|
|
61
|
-
expect(flatResponse.status).toBe(200)
|
|
62
|
-
const flatData = flatResponse.data
|
|
63
|
-
expect(flatData.default).toBe("/index.ts")
|
|
64
|
-
expect(flatData.files).toHaveLength(3)
|
|
65
|
-
expect(flatData.files[0].name).toMatch(/^\//)
|
|
66
|
-
|
|
67
|
-
// Test downloading non-existent file
|
|
68
|
-
try {
|
|
69
|
-
await axios.get("/api/snippets/download", {
|
|
70
|
-
params: { jsdelivr_path: "testuser/test-package@1.0.0/non-existent.ts" },
|
|
71
|
-
})
|
|
72
|
-
// If the request doesn't throw an error, fail the test
|
|
73
|
-
expect(true).toBe(false)
|
|
74
|
-
} catch (error: any) {
|
|
75
|
-
expect(error.status).toBe(404)
|
|
76
|
-
expect(error.data.error.message).toBe("Requested file not found")
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Test downloading non-existent package
|
|
80
|
-
try {
|
|
81
|
-
await axios.get("/api/snippets/download", {
|
|
82
|
-
params: { jsdelivr_path: "testuser/non-existent-package@1.0.0/index.ts" },
|
|
83
|
-
})
|
|
84
|
-
// If the request doesn't throw an error, fail the test
|
|
85
|
-
expect(true).toBe(false)
|
|
86
|
-
} catch (error: any) {
|
|
87
|
-
expect(error.status).toBe(404)
|
|
88
|
-
expect(error.data.error.message).toBe("Snippet not found")
|
|
89
|
-
}
|
|
90
|
-
})
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { getTestServer } from "bun-tests/fake-snippets-api/fixtures/get-test-server"
|
|
2
|
-
import { test, expect } from "bun:test"
|
|
3
|
-
|
|
4
|
-
test.skip("generate snippet from JLCPCB part number", async () => {
|
|
5
|
-
const { axios } = await getTestServer()
|
|
6
|
-
|
|
7
|
-
const response = await axios.post("/api/snippets/generate_from_jlcpcb", {
|
|
8
|
-
jlcpcb_part_number: "C46749",
|
|
9
|
-
})
|
|
10
|
-
expect(response.status).toBe(200)
|
|
11
|
-
expect(response.data.snippet).toBeDefined()
|
|
12
|
-
expect(response.data.snippet.unscoped_name).toBe("C46749")
|
|
13
|
-
expect(response.data.snippet.owner_name).toBe("testuser")
|
|
14
|
-
expect(response.data.snippet.snippet_type).toBe("package")
|
|
15
|
-
expect(response.data.snippet.code).toContain("export const NE555P")
|
|
16
|
-
})
|
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
import { getTestServer } from "bun-tests/fake-snippets-api/fixtures/get-test-server"
|
|
2
|
-
import { expect, test } from "bun:test"
|
|
3
|
-
import { snippetSchema } from "fake-snippets-api/lib/db/schema"
|
|
4
|
-
|
|
5
|
-
test("GET /api/snippets/get - should return snippet by snippet_id", async () => {
|
|
6
|
-
const { axios } = await getTestServer()
|
|
7
|
-
|
|
8
|
-
// First create a snippet
|
|
9
|
-
const newSnippetData = {
|
|
10
|
-
code: "console.log('Hello World')",
|
|
11
|
-
snippet_type: "package",
|
|
12
|
-
description: "A test snippet",
|
|
13
|
-
compiled_js: "console.log('Hello World')",
|
|
14
|
-
dts: "export function hello(): void;",
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const createResponse = await axios.post(
|
|
18
|
-
"/api/snippets/create",
|
|
19
|
-
newSnippetData,
|
|
20
|
-
)
|
|
21
|
-
expect(createResponse.status).toBe(200)
|
|
22
|
-
const createdSnippet = createResponse.data.snippet
|
|
23
|
-
|
|
24
|
-
// Get the created snippet using the /get endpoint
|
|
25
|
-
const getResponse = await axios.get("/api/snippets/get", {
|
|
26
|
-
params: { snippet_id: createdSnippet.snippet_id },
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
expect(getResponse.status).toBe(200)
|
|
30
|
-
const responseBody = getResponse.data
|
|
31
|
-
expect(responseBody.ok).toBe(true)
|
|
32
|
-
expect(responseBody.snippet).toEqual(snippetSchema.parse(createdSnippet))
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
test("GET /api/snippets/get - should return 404 if snippet not found", async () => {
|
|
36
|
-
const { axios } = await getTestServer()
|
|
37
|
-
|
|
38
|
-
try {
|
|
39
|
-
await axios.get("/api/snippets/get", {
|
|
40
|
-
params: { snippet_id: "non_existent_snippet_id" },
|
|
41
|
-
})
|
|
42
|
-
throw new Error("Expected request to fail")
|
|
43
|
-
} catch (error: any) {
|
|
44
|
-
expect(error.status).toBe(404)
|
|
45
|
-
expect(error.data.error.error_code).toBe("snippet_not_found")
|
|
46
|
-
expect(error.data.error.message).toBe(
|
|
47
|
-
'Snippet not found (searched using {"snippet_id":"non_existent_snippet_id"})',
|
|
48
|
-
)
|
|
49
|
-
}
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
test("GET /api/snippets/get - should return snippet by name and owner", async () => {
|
|
53
|
-
const { axios } = await getTestServer()
|
|
54
|
-
|
|
55
|
-
// First create a snippet
|
|
56
|
-
const newSnippetData = {
|
|
57
|
-
code: "console.log('Hello World')",
|
|
58
|
-
snippet_type: "package",
|
|
59
|
-
description: "A test snippet",
|
|
60
|
-
compiled_js: "console.log('Hello World')",
|
|
61
|
-
dts: "export function hello(): void;",
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const createResponse = await axios.post(
|
|
65
|
-
"/api/snippets/create",
|
|
66
|
-
newSnippetData,
|
|
67
|
-
)
|
|
68
|
-
expect(createResponse.status).toBe(200)
|
|
69
|
-
const createdSnippet = createResponse.data.snippet
|
|
70
|
-
|
|
71
|
-
// Get the snippet using name and owner
|
|
72
|
-
const getResponse = await axios.get("/api/snippets/get", {
|
|
73
|
-
params: {
|
|
74
|
-
name: createdSnippet.name,
|
|
75
|
-
owner_name: createdSnippet.owner_name,
|
|
76
|
-
},
|
|
77
|
-
})
|
|
78
|
-
|
|
79
|
-
expect(getResponse.status).toBe(200)
|
|
80
|
-
const responseBody = getResponse.data
|
|
81
|
-
expect(responseBody.ok).toBe(true)
|
|
82
|
-
expect(responseBody.snippet).toEqual(snippetSchema.parse(createdSnippet))
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
test("GET /api/snippets/get - should return snippet by unscoped_name and owner", async () => {
|
|
86
|
-
const { axios, db } = await getTestServer()
|
|
87
|
-
|
|
88
|
-
// First create a snippet
|
|
89
|
-
const snippet = {
|
|
90
|
-
unscoped_name: "test-package",
|
|
91
|
-
owner_name: "testuser",
|
|
92
|
-
code: "export const TestComponent = () => <div>Test</div>",
|
|
93
|
-
dts: "export declare const TestComponent: () => JSX.Element",
|
|
94
|
-
created_at: "2023-01-01T00:00:00Z",
|
|
95
|
-
updated_at: "2023-01-01T00:00:00Z",
|
|
96
|
-
name: "testuser/test-package",
|
|
97
|
-
snippet_type: "package",
|
|
98
|
-
description: "Test package",
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
db.addSnippet(snippet as any)
|
|
102
|
-
|
|
103
|
-
// Get the snippet using name and owner
|
|
104
|
-
const getResponse = await axios.get("/api/snippets/get", {
|
|
105
|
-
params: {
|
|
106
|
-
unscoped_name: snippet.unscoped_name,
|
|
107
|
-
owner_name: snippet.owner_name,
|
|
108
|
-
},
|
|
109
|
-
})
|
|
110
|
-
|
|
111
|
-
expect(getResponse.status).toBe(200)
|
|
112
|
-
const responseBody = getResponse.data
|
|
113
|
-
expect(responseBody.ok).toBe(true)
|
|
114
|
-
})
|
|
115
|
-
|
|
116
|
-
test("GET /api/snippets/get - should not return snippet if snippet is private and user is unauthenticated", async () => {
|
|
117
|
-
const { axios, db, unauthenticatedAxios } = await getTestServer()
|
|
118
|
-
|
|
119
|
-
// First create a snippet
|
|
120
|
-
const snippet = {
|
|
121
|
-
unscoped_name: "test-package",
|
|
122
|
-
owner_name: "testuser",
|
|
123
|
-
code: "export const TestComponent = () => <div>Test</div>",
|
|
124
|
-
dts: "export declare const TestComponent: () => JSX.Element",
|
|
125
|
-
created_at: "2023-01-01T00:00:00Z",
|
|
126
|
-
updated_at: "2023-01-01T00:00:00Z",
|
|
127
|
-
name: "testuser/test-package",
|
|
128
|
-
snippet_type: "package",
|
|
129
|
-
description: "Test package",
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
db.addSnippet(snippet as any)
|
|
133
|
-
|
|
134
|
-
const createdSnippet = db.packages[0]
|
|
135
|
-
|
|
136
|
-
const updatedSnippet = await axios.post("/api/snippets/update", {
|
|
137
|
-
snippet_id: createdSnippet.package_id,
|
|
138
|
-
is_private: true,
|
|
139
|
-
})
|
|
140
|
-
|
|
141
|
-
expect(updatedSnippet.status).toBe(200)
|
|
142
|
-
expect(updatedSnippet.data.snippet.is_private).toBe(true)
|
|
143
|
-
expect(updatedSnippet.data.snippet.is_public).toBe(false)
|
|
144
|
-
|
|
145
|
-
// Get the snippet using name and owner
|
|
146
|
-
const getResponse = await axios.post("/api/snippets/get", {
|
|
147
|
-
snippet_id: createdSnippet.package_id,
|
|
148
|
-
})
|
|
149
|
-
|
|
150
|
-
expect(getResponse.status).toBe(200)
|
|
151
|
-
const responseBody = getResponse.data
|
|
152
|
-
expect(responseBody.ok).toBe(true)
|
|
153
|
-
|
|
154
|
-
try {
|
|
155
|
-
await unauthenticatedAxios.post("/api/snippets/get", {
|
|
156
|
-
snippet_id: createdSnippet.package_id,
|
|
157
|
-
})
|
|
158
|
-
throw new Error("Expected request to fail")
|
|
159
|
-
} catch (error: any) {
|
|
160
|
-
expect(error.status).toBe(404)
|
|
161
|
-
expect(error.data.error.error_code).toBe("snippet_not_found")
|
|
162
|
-
}
|
|
163
|
-
})
|