@tscircuit/fake-snippets 0.0.66 → 0.0.68
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-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 +0 -11
- package/bun.lock +26 -75
- package/dist/bundle.js +32 -39
- 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/package.json +4 -4
- package/src/App.tsx +0 -11
- package/src/ContextProviders.tsx +2 -0
- package/src/components/CmdKMenu.tsx +19 -19
- package/src/components/DownloadButtonAndMenu.tsx +1 -4
- package/src/components/FAQ.tsx +3 -1
- package/src/components/FileSidebar.tsx +50 -1
- package/src/components/Footer.tsx +5 -2
- package/src/components/Header2.tsx +20 -9
- package/src/components/HeaderLogin.tsx +37 -54
- package/src/components/ImageWithFallback.tsx +37 -0
- package/src/components/JLCPCBImportDialog.tsx +45 -29
- package/src/components/PackageCard.tsx +2 -2
- 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/ViewPackagePage/components/ShikiCodeViewer.tsx +5 -28
- package/src/components/ViewPackagePage/components/important-files-view.tsx +1 -1
- package/src/components/ViewPackagePage/components/main-content-header.tsx +8 -8
- package/src/components/ViewPackagePage/components/mobile-sidebar.tsx +24 -14
- package/src/components/ViewPackagePage/components/package-header.tsx +7 -2
- package/src/components/dialogs/confirm-delete-package-dialog.tsx +8 -0
- package/src/components/dialogs/edit-package-details-dialog.tsx +145 -138
- package/src/components/package-port/CodeAndPreview.tsx +40 -19
- package/src/components/package-port/CodeEditor.tsx +21 -37
- package/src/components/package-port/CodeEditorHeader.tsx +1 -1
- package/src/components/package-port/EditorNav.tsx +3 -13
- package/src/hooks/use-global-store.ts +1 -0
- package/src/hooks/use-shiki-highlighter.ts +13 -6
- package/src/hooks/useFileManagement.ts +59 -0
- 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/lib/utils/isValidFileName.ts +5 -0
- package/src/pages/dashboard.tsx +4 -4
- package/src/pages/editor.tsx +20 -14
- package/src/pages/latest.tsx +25 -26
- package/src/pages/quickstart.tsx +5 -5
- package/src/pages/search.tsx +121 -20
- package/src/pages/trending.tsx +14 -58
- package/src/pages/user-profile.tsx +14 -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/OrderPreviewContent.tsx +0 -61
- package/src/components/PreviewContent.tsx +0 -372
- package/src/components/SnippetCard.tsx +0 -159
- package/src/components/SnippetList.tsx +0 -71
- package/src/components/ViewSnippetSidebar.tsx +0 -162
- package/src/components/dialogs/create-order-dialog.tsx +0 -146
- 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/preview.tsx +0 -44
- package/src/pages/view-order.tsx +0 -111
- package/src/pages/view-snippet.tsx +0 -166
|
@@ -1,148 +1,10 @@
|
|
|
1
|
-
import * as React from "react"
|
|
2
|
-
import { getImportsFromCode } from "@tscircuit/prompt-benchmarks/code-runner-utils"
|
|
3
|
-
import * as tscircuitCore from "@tscircuit/core"
|
|
4
|
-
import * as jscadFiber from "jscad-fiber"
|
|
5
1
|
import type { AnyCircuitElement } from "circuit-json"
|
|
6
|
-
import {
|
|
7
|
-
import { evalCompiledJs } from "@/hooks/use-run-tsx/eval-compiled-js"
|
|
8
|
-
import { constructCircuit } from "@/hooks/use-run-tsx/construct-circuit"
|
|
9
|
-
|
|
10
|
-
type GenerateCircuitJson = {
|
|
11
|
-
code: string
|
|
12
|
-
type: "board" | "footprint" | "package" | "model"
|
|
13
|
-
compiled_js: string
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// Keeping track of processed imports to avoid circular dependencies
|
|
17
|
-
const processedImports = new Set<string>()
|
|
18
|
-
|
|
19
|
-
async function processImport(
|
|
20
|
-
importName: string,
|
|
21
|
-
preSuppliedImports: Record<string, any>,
|
|
22
|
-
depth = 0,
|
|
23
|
-
code: string,
|
|
24
|
-
compiled_js: string,
|
|
25
|
-
): Promise<void> {
|
|
26
|
-
if (!importName.startsWith("@tsci/")) return
|
|
27
|
-
if (preSuppliedImports[importName]) return
|
|
28
|
-
if (processedImports.has(importName)) return
|
|
29
|
-
if (depth > 5) {
|
|
30
|
-
throw new Error(
|
|
31
|
-
`Max depth for imports reached when processing ${importName}`,
|
|
32
|
-
)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
processedImports.add(importName)
|
|
36
|
-
|
|
37
|
-
try {
|
|
38
|
-
// Process nested imports first
|
|
39
|
-
const nestedImports = getImportsFromCode(code)
|
|
40
|
-
|
|
41
|
-
// Filter out already processed imports and non-@tsci imports
|
|
42
|
-
const validNestedImports = nestedImports.filter(
|
|
43
|
-
(imp) =>
|
|
44
|
-
imp.startsWith("@tsci/") &&
|
|
45
|
-
!processedImports.has(imp) &&
|
|
46
|
-
!preSuppliedImports[imp],
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
// Process each valid nested import
|
|
50
|
-
for (const nestedImport of validNestedImports) {
|
|
51
|
-
await processImport(
|
|
52
|
-
nestedImport,
|
|
53
|
-
preSuppliedImports,
|
|
54
|
-
depth + 1,
|
|
55
|
-
code,
|
|
56
|
-
compiled_js,
|
|
57
|
-
)
|
|
58
|
-
}
|
|
59
|
-
// Set React in the global scope before evaluation
|
|
60
|
-
;(globalThis as any).React = React
|
|
61
|
-
const exports = evalCompiledJs(compiled_js).exports
|
|
62
|
-
|
|
63
|
-
// Only set the import if we successfully evaluated it
|
|
64
|
-
if (exports) {
|
|
65
|
-
preSuppliedImports[importName] = exports
|
|
66
|
-
}
|
|
67
|
-
} catch (e) {
|
|
68
|
-
processedImports.delete(importName) // Clean up on error
|
|
69
|
-
}
|
|
70
|
-
}
|
|
2
|
+
import { runTscircuitCode } from "@tscircuit/eval"
|
|
71
3
|
|
|
72
4
|
export const generateCircuitJson = async ({
|
|
73
5
|
code,
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
processedImports.clear()
|
|
79
|
-
|
|
80
|
-
// Set up pre-supplied imports
|
|
81
|
-
const preSuppliedImports: Record<string, any> = {
|
|
82
|
-
"@tscircuit/core": tscircuitCore,
|
|
83
|
-
react: React,
|
|
84
|
-
"jscad-fiber": jscadFiber,
|
|
85
|
-
}
|
|
86
|
-
;(globalThis as any).React = React
|
|
87
|
-
;(globalThis as any).createElement = React.createElement
|
|
88
|
-
|
|
89
|
-
try {
|
|
90
|
-
// Process all @tsci imports
|
|
91
|
-
const tsciImports = getImportsFromCode(code).filter((imp) =>
|
|
92
|
-
imp.startsWith("@tsci/"),
|
|
93
|
-
)
|
|
94
|
-
for (const importName of tsciImports) {
|
|
95
|
-
await processImport(importName, preSuppliedImports, 0, code, compiled_js)
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// Create require function for imports
|
|
99
|
-
const __tscircuit_require = (name: string) => {
|
|
100
|
-
if (!preSuppliedImports[name]) {
|
|
101
|
-
throw new Error(
|
|
102
|
-
`Import "${name}" not found (available imports: ${Object.keys(preSuppliedImports).join(", ")})`,
|
|
103
|
-
)
|
|
104
|
-
}
|
|
105
|
-
return preSuppliedImports[name]
|
|
106
|
-
}
|
|
107
|
-
;(globalThis as any).__tscircuit_require = __tscircuit_require
|
|
108
|
-
|
|
109
|
-
// Add a custom JSX runtime
|
|
110
|
-
;(globalThis as any).jsx = React.createElement
|
|
111
|
-
;(globalThis as any).jsxs = React.createElement
|
|
112
|
-
|
|
113
|
-
const { success, compiledTsx, error } = safeCompileTsx(code)
|
|
114
|
-
if (!success || !compiledTsx) {
|
|
115
|
-
throw new Error(
|
|
116
|
-
`Compile Error: ${error?.message || "Unknown compilation error"}`,
|
|
117
|
-
)
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
const module = evalCompiledJs(compiledTsx)
|
|
121
|
-
const componentExportKeys = Object.keys(module.exports).filter(
|
|
122
|
-
(key) => !key.startsWith("use"),
|
|
123
|
-
)
|
|
124
|
-
|
|
125
|
-
if (componentExportKeys.length > 1) {
|
|
126
|
-
throw new Error(
|
|
127
|
-
`Too many exports, only export one component. Exports: ${JSON.stringify(componentExportKeys)}`,
|
|
128
|
-
)
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const primaryKey = componentExportKeys[0]
|
|
132
|
-
|
|
133
|
-
// Create the user element with explicit React scope
|
|
134
|
-
const UserElm = function (props: any) {
|
|
135
|
-
return React.createElement(module.exports[primaryKey], props)
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// Construct and render the circuit
|
|
139
|
-
const circuit = constructCircuit({ UserElm, type })
|
|
140
|
-
|
|
141
|
-
// Wait for the circuit to settle
|
|
142
|
-
await circuit.renderUntilSettled()
|
|
143
|
-
|
|
144
|
-
return circuit.getCircuitJson() as AnyCircuitElement[]
|
|
145
|
-
} catch (e) {
|
|
146
|
-
throw new Error("Circuit generation failed!")
|
|
147
|
-
}
|
|
6
|
+
}: {
|
|
7
|
+
code: string
|
|
8
|
+
}): Promise<AnyCircuitElement[]> => {
|
|
9
|
+
return (await runTscircuitCode(code)) as any
|
|
148
10
|
}
|
|
@@ -2,7 +2,6 @@ import { afterEach } from "bun:test"
|
|
|
2
2
|
import defaultAxios from "redaxios"
|
|
3
3
|
import { startServer } from "./start-server"
|
|
4
4
|
import { DbClient } from "fake-snippets-api/lib/db/db-client"
|
|
5
|
-
import getPort from "get-port"
|
|
6
5
|
|
|
7
6
|
process.env.BUN_TEST = "true"
|
|
8
7
|
interface TestFixture {
|
|
@@ -16,12 +15,10 @@ interface TestFixture {
|
|
|
16
15
|
}
|
|
17
16
|
|
|
18
17
|
export const getTestServer = async (): Promise<TestFixture> => {
|
|
19
|
-
const port = await getPort()
|
|
20
18
|
const testInstanceId = Math.random().toString(36).substring(2, 15)
|
|
21
19
|
const testDbName = `testdb${testInstanceId}`
|
|
22
20
|
|
|
23
|
-
const { server, db } = await startServer({
|
|
24
|
-
port,
|
|
21
|
+
const { server, db, port } = await startServer({
|
|
25
22
|
testDbName,
|
|
26
23
|
})
|
|
27
24
|
|
|
@@ -11,7 +11,7 @@ import { createDatabase } from "fake-snippets-api/lib/db/db-client"
|
|
|
11
11
|
export const startServer = async ({
|
|
12
12
|
port,
|
|
13
13
|
testDbName,
|
|
14
|
-
}: { port
|
|
14
|
+
}: { port?: number; testDbName: string }) => {
|
|
15
15
|
const winterspecBundle = await createWinterSpecBundleFromDir(
|
|
16
16
|
join(import.meta.dir, "../../../fake-snippets-api/routes"),
|
|
17
17
|
)
|
|
@@ -37,8 +37,12 @@ export const startServer = async ({
|
|
|
37
37
|
middleware,
|
|
38
38
|
})
|
|
39
39
|
},
|
|
40
|
-
port,
|
|
40
|
+
port: port ?? 0,
|
|
41
41
|
})
|
|
42
42
|
|
|
43
|
-
return {
|
|
43
|
+
return {
|
|
44
|
+
server: { ...server, stop: () => server.stop() },
|
|
45
|
+
db,
|
|
46
|
+
port: server.port,
|
|
47
|
+
}
|
|
44
48
|
}
|
|
@@ -1,69 +1,33 @@
|
|
|
1
1
|
import { getTestServer } from "bun-tests/fake-snippets-api/fixtures/get-test-server"
|
|
2
2
|
import { test, expect } from "bun:test"
|
|
3
3
|
|
|
4
|
-
test("create order_quote with only
|
|
5
|
-
const {
|
|
6
|
-
axios,
|
|
7
|
-
seed: { order },
|
|
8
|
-
} = await getTestServer()
|
|
9
|
-
|
|
10
|
-
const response = await axios.post("/api/order_quotes/create", {
|
|
11
|
-
vendor_name: "jlcpcb",
|
|
12
|
-
circuit_json: order.circuit_json,
|
|
13
|
-
})
|
|
4
|
+
test("create order_quote with only package_release_id (✅)", async () => {
|
|
5
|
+
const { axios, jane_axios } = await getTestServer()
|
|
14
6
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
7
|
+
const pkg = await jane_axios
|
|
8
|
+
.post("/api/packages/create", {
|
|
9
|
+
name: "jane/test-package",
|
|
10
|
+
})
|
|
11
|
+
.then((res) => res.data.package)
|
|
18
12
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
13
|
+
const packageRelease = await jane_axios
|
|
14
|
+
.post("/api/package_releases/create", {
|
|
15
|
+
package_id: pkg.package_id,
|
|
16
|
+
version: "1.0.0",
|
|
17
|
+
is_latest: true,
|
|
18
|
+
})
|
|
19
|
+
.then((res) => res.data.package_release)
|
|
24
20
|
|
|
21
|
+
await jane_axios.post(`/api/package_files/create`, {
|
|
22
|
+
package_release_id: packageRelease.package_release_id,
|
|
23
|
+
file_path: "/dist/index.js",
|
|
24
|
+
content_text: "console.log('Hello, world!');",
|
|
25
|
+
})
|
|
25
26
|
const response = await axios.post("/api/order_quotes/create", {
|
|
26
27
|
vendor_name: "jlcpcb",
|
|
27
|
-
package_release_id: packageRelease
|
|
28
|
+
package_release_id: packageRelease.package_release_id,
|
|
28
29
|
})
|
|
29
30
|
|
|
30
31
|
expect(response.status).toBe(200)
|
|
31
32
|
expect(response.data.order_quote_id).toBeDefined()
|
|
32
33
|
})
|
|
33
|
-
|
|
34
|
-
test("create order_quote with both circuit_json and package_release_id (✅)", async () => {
|
|
35
|
-
const {
|
|
36
|
-
axios,
|
|
37
|
-
seed: { order, packageRelease },
|
|
38
|
-
} = await getTestServer()
|
|
39
|
-
|
|
40
|
-
const response = await axios
|
|
41
|
-
.post("/api/order_quotes/create", {
|
|
42
|
-
vendor_name: "jlcpcb",
|
|
43
|
-
circuit_json: order.circuit_json,
|
|
44
|
-
package_release_id: packageRelease!.package_release_id,
|
|
45
|
-
})
|
|
46
|
-
.catch((error) => error) // Capture response even on error
|
|
47
|
-
|
|
48
|
-
// Expecting backend to fail with 400
|
|
49
|
-
expect(response?.status).toBe(400)
|
|
50
|
-
expect(response?.data.message).toContain(
|
|
51
|
-
"You must provide either circuit_json or package_release_id, but not both.",
|
|
52
|
-
)
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
test("create order_quote with neither circuit_json nor package_release_id (✅)", async () => {
|
|
56
|
-
const { axios } = await getTestServer()
|
|
57
|
-
|
|
58
|
-
const response = await axios
|
|
59
|
-
.post("/api/order_quotes/create", {
|
|
60
|
-
vendor_name: "jlcpcb",
|
|
61
|
-
})
|
|
62
|
-
.catch((error) => error) // Capture response even on error
|
|
63
|
-
|
|
64
|
-
// Expecting backend to fail with 400
|
|
65
|
-
expect(response?.status).toBe(400)
|
|
66
|
-
expect(response?.data.message).toContain(
|
|
67
|
-
"You must provide either circuit_json or package_release_id.",
|
|
68
|
-
)
|
|
69
|
-
})
|
|
@@ -398,7 +398,7 @@ test("create_or_update - 404 for npm_pack_output without is_release_tarball", as
|
|
|
398
398
|
}
|
|
399
399
|
})
|
|
400
400
|
|
|
401
|
-
test("update package file with content_base64", async () => {
|
|
401
|
+
test.skip("update package file with content_base64", async () => {
|
|
402
402
|
const { axios } = await getTestServer()
|
|
403
403
|
|
|
404
404
|
const packageResponse = await axios.post("/api/packages/create", {
|
|
@@ -506,7 +506,7 @@ test("create_or_update detects correct content mimetype", async () => {
|
|
|
506
506
|
}
|
|
507
507
|
})
|
|
508
508
|
|
|
509
|
-
test("create_or_update respects provided content_mimetype", async () => {
|
|
509
|
+
test.skip("create_or_update respects provided content_mimetype", async () => {
|
|
510
510
|
const { axios } = await getTestServer()
|
|
511
511
|
|
|
512
512
|
const packageResponse = await axios.post("/api/packages/create", {
|
|
@@ -69,7 +69,7 @@ test("update package release using package_name_with_version", async () => {
|
|
|
69
69
|
expect(updatedRelease?.is_locked).toBe(true)
|
|
70
70
|
})
|
|
71
71
|
|
|
72
|
-
test("update package release - handle is_latest flag", async () => {
|
|
72
|
+
test.skip("update package release - handle is_latest flag", async () => {
|
|
73
73
|
const { axios, db } = await getTestServer()
|
|
74
74
|
|
|
75
75
|
// Create a package
|
|
@@ -27,17 +27,6 @@ export default () => (
|
|
|
27
27
|
<A555Timer name="U1" />
|
|
28
28
|
</board>
|
|
29
29
|
)`.trim(),
|
|
30
|
-
type: "board",
|
|
31
|
-
compiled_js: `
|
|
32
|
-
"use strict";
|
|
33
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
34
|
-
exports.A555Timer = void 0;
|
|
35
|
-
const A555Timer = ({ name }) => /*#__PURE__*/React.createElement("chip", {
|
|
36
|
-
name: name,
|
|
37
|
-
footprint: "dip8"
|
|
38
|
-
});
|
|
39
|
-
exports.A555Timer = A555Timer;
|
|
40
|
-
`.trim(),
|
|
41
30
|
})
|
|
42
31
|
// create a package file
|
|
43
32
|
const pkg_file = await axios.post("/api/package_files/create", {
|