@tscircuit/fake-snippets 0.0.106 → 0.0.108
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 +84 -25
- package/biome.json +7 -1
- package/bun-tests/fake-snippets-api/routes/package_builds/get.test.ts +0 -15
- package/bun-tests/fake-snippets-api/routes/package_builds/list.test.ts +0 -12
- package/dist/bundle.js +360 -434
- package/dist/index.d.ts +26 -15
- package/dist/index.js +40 -21
- package/dist/schema.d.ts +32 -24
- package/dist/schema.js +7 -5
- package/fake-snippets-api/lib/db/db-client.ts +19 -1
- package/fake-snippets-api/lib/db/schema.ts +6 -3
- package/fake-snippets-api/lib/db/seed.ts +23 -12
- package/fake-snippets-api/lib/public-mapping/public-map-package-build.ts +0 -3
- package/fake-snippets-api/lib/public-mapping/public-map-package-release.ts +3 -0
- package/fake-snippets-api/routes/api/package_builds/list.ts +0 -1
- package/package.json +3 -2
- package/src/App.tsx +27 -9
- package/src/components/FileSidebar.tsx +14 -159
- package/src/components/PackageBreadcrumb.tsx +111 -0
- package/src/components/ViewPackagePage/components/mobile-sidebar.tsx +1 -1
- package/src/components/ViewPackagePage/components/sidebar-about-section.tsx +18 -2
- package/src/components/ViewPackagePage/components/sidebar-releases-section.tsx +18 -8
- package/src/components/preview/BuildsList.tsx +84 -167
- package/src/components/preview/ConnectedPackagesList.tsx +92 -62
- package/src/components/preview/ConnectedRepoOverview.tsx +171 -155
- package/src/components/preview/{ConnectedRepoDashboard.tsx → PackageReleasesDashboard.tsx} +31 -69
- package/src/components/preview/index.tsx +20 -154
- package/src/hooks/use-package-builds.ts +0 -48
- package/src/hooks/use-package-release-by-id-or-version.ts +36 -0
- package/src/hooks/use-package-release.ts +32 -0
- package/src/index.css +24 -0
- package/src/lib/utils/isUuid.ts +5 -0
- package/src/lib/utils/transformFilesToTreeData.tsx +195 -0
- package/src/pages/404.tsx +3 -5
- package/src/pages/preview-release.tsx +269 -0
- package/src/pages/release-builds.tsx +99 -0
- package/src/pages/release-detail.tsx +120 -0
- package/src/pages/releases.tsx +55 -0
- package/fake-snippets-api/routes/api/package_builds/latest.ts +0 -109
- package/src/hooks/use-snippets-base-api-url.ts +0 -3
- package/src/pages/preview-build.tsx +0 -380
- package/src/pages/view-connected-repo.tsx +0 -49
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
tscircuit.com is a React-based web application for creating, sharing, and managing electronic circuit designs using TypeScript and React. It features a circuit editor, package management system, AI-assisted design tools, and visualization of PCB layouts and 3D models.
|
|
8
|
+
|
|
9
|
+
## Development Commands
|
|
10
|
+
|
|
11
|
+
- `bun run dev` - Start development server (builds fake API and runs on localhost:5173)
|
|
12
|
+
- `bun run build` - Full production build (generates images, sitemap, builds fake API, compiles TypeScript, and builds with Vite)
|
|
13
|
+
- `bun run typecheck` - Run TypeScript type checking without emitting files
|
|
14
|
+
- `bun run format` - Format code using Biome
|
|
15
|
+
- `bun run lint` - Check code formatting with Biome
|
|
16
|
+
- `bun run playwright` - Run Playwright end-to-end tests
|
|
17
|
+
- `bun run playwright:update` - Update Playwright test snapshots
|
|
18
|
+
- `bun run snapshot` - Interactive snapshot updating tool (prompts for specific test file)
|
|
19
|
+
|
|
20
|
+
### Fake API Development
|
|
21
|
+
- `bun run build:fake-api` - Build the complete fake API (TypeScript compilation, bundle generation, schema building)
|
|
22
|
+
- `bun run dev:registry` - Run dev server using registry API at localhost:3100
|
|
23
|
+
|
|
24
|
+
## Architecture
|
|
25
|
+
|
|
26
|
+
### Frontend Structure
|
|
27
|
+
- **React SPA** with Vite bundler, using Wouter for routing and lazy-loaded pages
|
|
28
|
+
- **State Management**: Zustand for global state, React Query for server state
|
|
29
|
+
- **UI Framework**: Tailwind CSS with Radix UI components and custom shadcn/ui components
|
|
30
|
+
- **Code Editor**: CodeMirror 6 with TypeScript support and AI completion
|
|
31
|
+
|
|
32
|
+
### API Architecture
|
|
33
|
+
- **Fake API**: Development API built with Winterspec, providing full backend simulation
|
|
34
|
+
- **Database Schema**: Zod-validated schemas for packages, builds, releases, snippets, accounts, orders
|
|
35
|
+
- **Authentication**: Session-based auth with GitHub integration
|
|
36
|
+
|
|
37
|
+
### Key Domains
|
|
38
|
+
- **Packages**: Reusable circuit components with versioning and releases
|
|
39
|
+
- **Package Builds**: Compilation artifacts with build status and logs
|
|
40
|
+
- **Package Releases**: Published versions with metadata and assets
|
|
41
|
+
- **Snippets**: Legacy circuit designs (being migrated to packages)
|
|
42
|
+
- **Circuit JSON**: Standard format for circuit data interchange
|
|
43
|
+
|
|
44
|
+
### File Organization
|
|
45
|
+
- `src/components/` - Reusable UI components
|
|
46
|
+
- `src/pages/` - Route-based page components
|
|
47
|
+
- `src/hooks/` - Custom React hooks for data fetching and state
|
|
48
|
+
- `src/lib/` - Utilities, constants, and helper functions
|
|
49
|
+
- `fake-snippets-api/` - Mock API implementation with Winterspec
|
|
50
|
+
- `playwright-tests/` - End-to-end tests with visual regression snapshots
|
|
51
|
+
|
|
52
|
+
## Testing Strategy
|
|
53
|
+
|
|
54
|
+
Uses Playwright for end-to-end testing with visual regression snapshots. Tests cover critical user flows including editor functionality, package management, authentication, and responsive design across viewport sizes.
|
|
55
|
+
|
|
56
|
+
## Key Technical Patterns
|
|
57
|
+
|
|
58
|
+
### Data Fetching
|
|
59
|
+
- React Query for server state with custom hooks (use-package-*, use-snippet-*, etc.)
|
|
60
|
+
- Fake API provides development backend with realistic data simulation
|
|
61
|
+
- SSR support via Vercel for SEO and performance
|
|
62
|
+
|
|
63
|
+
### Circuit Visualization
|
|
64
|
+
- Multiple viewers: PCB viewer, schematic viewer, 3D viewer, assembly viewer
|
|
65
|
+
- SVG-based rendering with interactive controls
|
|
66
|
+
- Real-time preview updates during code editing
|
|
67
|
+
|
|
68
|
+
### Code Compilation
|
|
69
|
+
- TypeScript compilation in browser using Monaco/TypeScript compiler API
|
|
70
|
+
- Circuit JSON generation from TypeScript code
|
|
71
|
+
- Error handling and display for compilation issues
|
|
72
|
+
|
|
73
|
+
### Package Management
|
|
74
|
+
- Package files with hierarchical structure
|
|
75
|
+
- Build artifacts and release management
|
|
76
|
+
- GitHub integration for repository linking
|
|
77
|
+
|
|
78
|
+
## Environment Variables
|
|
79
|
+
|
|
80
|
+
Development AI testing requires:
|
|
81
|
+
```bash
|
|
82
|
+
VITE_USE_DIRECT_AI_REQUESTS=true
|
|
83
|
+
VITE_ANTHROPIC_API_KEY=<your-key-here>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Build Tools
|
|
87
|
+
|
|
88
|
+
- **Bundler**: Vite with React plugin and image optimization
|
|
89
|
+
- **TypeScript**: Strict mode with path aliases (@/* → src/*)
|
|
90
|
+
- **Styling**: Tailwind CSS with custom design tokens
|
|
91
|
+
- **Code Quality**: Biome for formatting and linting
|
|
92
|
+
- **Package Manager**: Bun for fast installs and script execution
|
package/api/generated-index.js
CHANGED
|
@@ -31,7 +31,7 @@ const PREFETCHABLE_PAGES = new Set([
|
|
|
31
31
|
"latest",
|
|
32
32
|
"settings",
|
|
33
33
|
"quickstart",
|
|
34
|
-
"
|
|
34
|
+
"releases",
|
|
35
35
|
])
|
|
36
36
|
|
|
37
37
|
const pageDescriptions = {
|
|
@@ -51,8 +51,7 @@ const pageDescriptions = {
|
|
|
51
51
|
"Get started quickly with tscircuit. Create new circuit packages, import components from JLCPCB, or start from templates to begin your electronic design journey.",
|
|
52
52
|
settings:
|
|
53
53
|
"Manage your tscircuit account settings, shipping information, and preferences for electronic design and PCB ordering.",
|
|
54
|
-
"
|
|
55
|
-
"View and manage your connected repositories. Monitor repository status, access build information, and configure build options.",
|
|
54
|
+
releases: "View all package releases, access build information.",
|
|
56
55
|
}
|
|
57
56
|
|
|
58
57
|
function getPageDescription(pageName) {
|
|
@@ -90,7 +89,10 @@ function getHtmlWithModifiedSeoTags({
|
|
|
90
89
|
`
|
|
91
90
|
|
|
92
91
|
// First replace SEO tags
|
|
93
|
-
let modifiedHtml = `${htmlContent.substring(
|
|
92
|
+
let modifiedHtml = `${htmlContent.substring(
|
|
93
|
+
0,
|
|
94
|
+
seoStartIndex,
|
|
95
|
+
)}${seoTags}${htmlContent.substring(seoEndIndex)}`
|
|
94
96
|
|
|
95
97
|
// Then handle SSR data injection
|
|
96
98
|
if (ssrPackageData) {
|
|
@@ -177,21 +179,25 @@ async function handleDatasheetPage(req, res) {
|
|
|
177
179
|
|
|
178
180
|
async function handleCustomPackageHtml(req, res) {
|
|
179
181
|
// Get the author and package name
|
|
180
|
-
const [_, author, unscopedPackageName] = req.url
|
|
182
|
+
const [_, author, unscopedPackageName, other] = req.url
|
|
183
|
+
.split("?")[0]
|
|
184
|
+
.split("/")
|
|
185
|
+
if (other == "releases" || other == "release") {
|
|
186
|
+
throw new Error("Release route")
|
|
187
|
+
}
|
|
181
188
|
if (!author || !unscopedPackageName) {
|
|
182
189
|
throw new Error("Invalid author/package URL")
|
|
183
190
|
}
|
|
184
191
|
if (author === "datasheets") {
|
|
185
192
|
throw new Error("Datasheet route")
|
|
186
193
|
}
|
|
187
|
-
if (author === "build" || unscopedPackageName === "view-connected-repo") {
|
|
188
|
-
throw new Error("Build route - not a package")
|
|
189
|
-
}
|
|
190
194
|
|
|
191
195
|
const packageNotFoundHtml = getHtmlWithModifiedSeoTags({
|
|
192
196
|
title: "Package Not Found - tscircuit",
|
|
193
197
|
description: `The package ${author}/${unscopedPackageName} could not be found.`,
|
|
194
|
-
canonicalUrl: `${BASE_URL}/${he.encode(author)}/${he.encode(
|
|
198
|
+
canonicalUrl: `${BASE_URL}/${he.encode(author)}/${he.encode(
|
|
199
|
+
unscopedPackageName,
|
|
200
|
+
)}`,
|
|
195
201
|
})
|
|
196
202
|
const packageDetails = await ky
|
|
197
203
|
.get(`${REGISTRY_URL}/packages/get`, {
|
|
@@ -250,19 +256,29 @@ async function handleCustomPackageHtml(req, res) {
|
|
|
250
256
|
}
|
|
251
257
|
|
|
252
258
|
const description = he.encode(
|
|
253
|
-
`${
|
|
259
|
+
`${
|
|
260
|
+
packageInfo.description ||
|
|
261
|
+
packageInfo.ai_description ||
|
|
262
|
+
"A tscircuit component created by " + author
|
|
263
|
+
} ${packageInfo.ai_usage_instructions ?? ""}`,
|
|
254
264
|
)
|
|
255
265
|
const title = he.encode(`${packageInfo.name} - tscircuit`)
|
|
256
266
|
|
|
257
267
|
const allowedViews = ["schematic", "pcb", "assembly", "3d"]
|
|
258
268
|
const defaultView = packageInfo.default_view || "pcb"
|
|
259
269
|
const thumbnailView = allowedViews.includes(defaultView) ? defaultView : "pcb"
|
|
260
|
-
const imageUrl = `${REGISTRY_URL}/packages/images/${he.encode(
|
|
270
|
+
const imageUrl = `${REGISTRY_URL}/packages/images/${he.encode(
|
|
271
|
+
author,
|
|
272
|
+
)}/${he.encode(unscopedPackageName)}/${thumbnailView}.png?fs_sha=${
|
|
273
|
+
packageInfo.latest_package_release_fs_sha
|
|
274
|
+
}`
|
|
261
275
|
|
|
262
276
|
const html = getHtmlWithModifiedSeoTags({
|
|
263
277
|
title,
|
|
264
278
|
description,
|
|
265
|
-
canonicalUrl: `${BASE_URL}/${he.encode(author)}/${he.encode(
|
|
279
|
+
canonicalUrl: `${BASE_URL}/${he.encode(author)}/${he.encode(
|
|
280
|
+
unscopedPackageName,
|
|
281
|
+
)}`,
|
|
266
282
|
imageUrl,
|
|
267
283
|
ssrPackageData: { package: packageInfo, packageRelease, packageFiles },
|
|
268
284
|
})
|
|
@@ -273,7 +289,6 @@ async function handleCustomPackageHtml(req, res) {
|
|
|
273
289
|
res.setHeader("Vary", "Accept-Encoding")
|
|
274
290
|
res.status(200).send(html)
|
|
275
291
|
}
|
|
276
|
-
|
|
277
292
|
async function handleCustomPage(req, res) {
|
|
278
293
|
const [_, page] = req.url.split("?")[0].split("/")
|
|
279
294
|
|
|
@@ -299,6 +314,57 @@ async function handleCustomPage(req, res) {
|
|
|
299
314
|
res.status(200).send(html)
|
|
300
315
|
}
|
|
301
316
|
|
|
317
|
+
async function handleReleasePreview(req, res) {
|
|
318
|
+
const [_, author, unscopedPackageName, releaseId] = req.url
|
|
319
|
+
.split("?")[0]
|
|
320
|
+
.split("/")
|
|
321
|
+
|
|
322
|
+
if (!author || !unscopedPackageName || !releaseId) {
|
|
323
|
+
throw new Error("Invalid author/package/release URL")
|
|
324
|
+
}
|
|
325
|
+
const packageDetails = await ky
|
|
326
|
+
.get(`${REGISTRY_URL}/packages/get`, {
|
|
327
|
+
searchParams: {
|
|
328
|
+
name: `${author}/${unscopedPackageName}`,
|
|
329
|
+
},
|
|
330
|
+
})
|
|
331
|
+
.json()
|
|
332
|
+
.catch((e) => {
|
|
333
|
+
if (String(e).includes("404")) {
|
|
334
|
+
return null
|
|
335
|
+
}
|
|
336
|
+
throw e
|
|
337
|
+
})
|
|
338
|
+
const packageNotFoundHtml = getHtmlWithModifiedSeoTags({
|
|
339
|
+
title: "Package Not Found - tscircuit",
|
|
340
|
+
description: `Release for package ${author}/${unscopedPackageName} could not be found.`,
|
|
341
|
+
canonicalUrl: `${BASE_URL}/${he.encode(author)}/${he.encode(
|
|
342
|
+
unscopedPackageName,
|
|
343
|
+
)}`,
|
|
344
|
+
})
|
|
345
|
+
if (!packageDetails) {
|
|
346
|
+
res.setHeader("Content-Type", "text/html; charset=utf-8")
|
|
347
|
+
res.setHeader("Cache-Control", cacheControlHeader)
|
|
348
|
+
res.setHeader("Vary", "Accept-Encoding")
|
|
349
|
+
res.status(404).send(packageNotFoundHtml)
|
|
350
|
+
return
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
const { package: packageInfo } = packageDetails
|
|
354
|
+
const title = he.encode(`Release preview for ${packageInfo.name} - tscircuit`)
|
|
355
|
+
|
|
356
|
+
const html = getHtmlWithModifiedSeoTags({
|
|
357
|
+
title,
|
|
358
|
+
description: pageDescriptions["releases"],
|
|
359
|
+
ssrPackageData: { package: packageInfo },
|
|
360
|
+
})
|
|
361
|
+
|
|
362
|
+
res.setHeader("Content-Type", "text/html; charset=utf-8")
|
|
363
|
+
res.setHeader("Cache-Control", cacheControlHeader)
|
|
364
|
+
res.setHeader("Vary", "Accept-Encoding")
|
|
365
|
+
res.status(200).send(html)
|
|
366
|
+
}
|
|
367
|
+
|
|
302
368
|
export default async function handler(req, res) {
|
|
303
369
|
const urlPath = req.url.split("?")[0]
|
|
304
370
|
if (urlPath === "/api/generated-index") {
|
|
@@ -311,22 +377,15 @@ export default async function handler(req, res) {
|
|
|
311
377
|
|
|
312
378
|
const pathParts = req.url.split("?")[0].split("/")
|
|
313
379
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
const html = getHtmlWithModifiedSeoTags({
|
|
317
|
-
title: `Preview Build For ${pathParts[2]} - tscircuit`,
|
|
318
|
-
description: pageDescription,
|
|
319
|
-
canonicalUrl: `${BASE_URL}/build/${pathParts[2]}`,
|
|
320
|
-
})
|
|
321
|
-
res.setHeader("Content-Type", "text/html; charset=utf-8")
|
|
322
|
-
res.setHeader("Cache-Control", cacheControlHeader)
|
|
323
|
-
res.setHeader("Vary", "Accept-Encoding")
|
|
324
|
-
res.status(200).send(html)
|
|
380
|
+
try {
|
|
381
|
+
await handleCustomPackageHtml(req, res)
|
|
325
382
|
return
|
|
383
|
+
} catch (e) {
|
|
384
|
+
console.warn(e)
|
|
326
385
|
}
|
|
327
386
|
|
|
328
387
|
try {
|
|
329
|
-
await
|
|
388
|
+
await handleReleasePreview(req, res)
|
|
330
389
|
return
|
|
331
390
|
} catch (e) {
|
|
332
391
|
console.warn(e)
|
package/biome.json
CHANGED
|
@@ -8,7 +8,13 @@
|
|
|
8
8
|
"indentStyle": "space"
|
|
9
9
|
},
|
|
10
10
|
"files": {
|
|
11
|
-
"ignore": [
|
|
11
|
+
"ignore": [
|
|
12
|
+
"cosmos-export",
|
|
13
|
+
"dist",
|
|
14
|
+
"package.json",
|
|
15
|
+
".vercel",
|
|
16
|
+
"src/index.css"
|
|
17
|
+
]
|
|
12
18
|
},
|
|
13
19
|
"javascript": {
|
|
14
20
|
"formatter": {
|
|
@@ -71,9 +71,6 @@ test("GET /api/package_builds/get - returns 403 for unauthorized package build a
|
|
|
71
71
|
build_error_last_updated_at: new Date().toISOString(),
|
|
72
72
|
build_logs: null,
|
|
73
73
|
preview_url: "https://preview.tscircuit.com/pb_test",
|
|
74
|
-
branch_name: "main",
|
|
75
|
-
commit_message: "Test build",
|
|
76
|
-
commit_author: "jane.doe",
|
|
77
74
|
})
|
|
78
75
|
|
|
79
76
|
const res = await axios.get(
|
|
@@ -126,9 +123,6 @@ test("GET /api/package_builds/get - successfully returns package build with logs
|
|
|
126
123
|
).toISOString(),
|
|
127
124
|
build_logs: buildLogs.join(" "),
|
|
128
125
|
preview_url: "https://preview.tscircuit.com/pb_1a2b3c4d",
|
|
129
|
-
branch_name: "main",
|
|
130
|
-
commit_message: "Add new LED component with improved brightness control",
|
|
131
|
-
commit_author: "john.doe",
|
|
132
126
|
})
|
|
133
127
|
|
|
134
128
|
const res = await axios.get(
|
|
@@ -174,9 +168,6 @@ test("GET /api/package_builds/get - returns package build without logs when incl
|
|
|
174
168
|
build_error_last_updated_at: new Date().toISOString(),
|
|
175
169
|
build_logs: "Some build logs",
|
|
176
170
|
preview_url: "https://preview.tscircuit.com/pb_test",
|
|
177
|
-
branch_name: "main",
|
|
178
|
-
commit_message: "Test build",
|
|
179
|
-
commit_author: "john.doe",
|
|
180
171
|
})
|
|
181
172
|
|
|
182
173
|
const res = await axios.get(
|
|
@@ -222,9 +213,6 @@ test("GET /api/package_builds/get - handles build with errors", async () => {
|
|
|
222
213
|
build_error_last_updated_at: new Date().toISOString(),
|
|
223
214
|
build_logs: null,
|
|
224
215
|
preview_url: null,
|
|
225
|
-
branch_name: "feature/new-component",
|
|
226
|
-
commit_message: "Add broken component",
|
|
227
|
-
commit_author: "john.doe",
|
|
228
216
|
})
|
|
229
217
|
|
|
230
218
|
const res = await axios.get(
|
|
@@ -274,9 +262,6 @@ test("GET /api/package_builds/get - handles build in progress", async () => {
|
|
|
274
262
|
build_error_last_updated_at: new Date().toISOString(),
|
|
275
263
|
build_logs: null,
|
|
276
264
|
preview_url: null,
|
|
277
|
-
branch_name: "main",
|
|
278
|
-
commit_message: "Building in progress",
|
|
279
|
-
commit_author: "john.doe",
|
|
280
265
|
})
|
|
281
266
|
|
|
282
267
|
const res = await axios.get(
|
|
@@ -125,9 +125,6 @@ test("GET /api/package_builds/list - returns created builds", async () => {
|
|
|
125
125
|
).toISOString(),
|
|
126
126
|
build_logs: null,
|
|
127
127
|
preview_url: "https://preview.tscircuit.com/pb_1a2b3c4d",
|
|
128
|
-
branch_name: "main",
|
|
129
|
-
commit_message: "Add new LED component with improved brightness control",
|
|
130
|
-
commit_author: "john.doe",
|
|
131
128
|
})
|
|
132
129
|
|
|
133
130
|
const res = await axios.get(
|
|
@@ -175,9 +172,6 @@ test("GET /api/package_builds/list - sorts builds by created_at descending", asy
|
|
|
175
172
|
).toISOString(),
|
|
176
173
|
build_logs: null,
|
|
177
174
|
preview_url: "https://preview.tscircuit.com/pb_1",
|
|
178
|
-
branch_name: "main",
|
|
179
|
-
commit_message: "First build",
|
|
180
|
-
commit_author: "john.doe",
|
|
181
175
|
})
|
|
182
176
|
|
|
183
177
|
db.addPackageBuild({
|
|
@@ -210,9 +204,6 @@ test("GET /api/package_builds/list - sorts builds by created_at descending", asy
|
|
|
210
204
|
).toISOString(),
|
|
211
205
|
build_logs: null,
|
|
212
206
|
preview_url: "https://preview.tscircuit.com/pb_2",
|
|
213
|
-
branch_name: "main",
|
|
214
|
-
commit_message: "Second build",
|
|
215
|
-
commit_author: "john.doe",
|
|
216
207
|
})
|
|
217
208
|
|
|
218
209
|
const res = await axios.get(
|
|
@@ -286,9 +277,6 @@ test("GET /api/package_builds/list - returns created builds with logs or not", a
|
|
|
286
277
|
).toISOString(),
|
|
287
278
|
build_logs: buildLogs.join(" "),
|
|
288
279
|
preview_url: "https://preview.tscircuit.com/pb_1a2b3c4d",
|
|
289
|
-
branch_name: "main",
|
|
290
|
-
commit_message: "Add new LED component with improved brightness control",
|
|
291
|
-
commit_author: "john.doe",
|
|
292
280
|
})
|
|
293
281
|
|
|
294
282
|
const resWithoutLogs = await axios.get(
|