@tscircuit/fake-snippets 0.0.105 → 0.0.107
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 +3 -4
- package/bun-tests/fake-snippets-api/routes/package_builds/get.test.ts +294 -0
- package/bun-tests/fake-snippets-api/routes/package_builds/list.test.ts +304 -0
- package/dist/bundle.js +698 -335
- package/dist/index.d.ts +147 -4
- package/dist/index.js +195 -7
- package/dist/schema.d.ts +206 -1
- package/dist/schema.js +31 -2
- package/fake-snippets-api/lib/db/db-client.ts +60 -3
- package/fake-snippets-api/lib/db/schema.ts +31 -0
- package/fake-snippets-api/lib/db/seed.ts +139 -2
- package/fake-snippets-api/lib/public-mapping/public-map-package-build.ts +41 -0
- package/fake-snippets-api/routes/api/package_builds/get.ts +70 -0
- package/fake-snippets-api/routes/api/package_builds/list.ts +97 -0
- package/package.json +3 -2
- package/src/App.tsx +21 -5
- package/src/components/PackageBreadcrumb.tsx +111 -0
- package/src/components/ViewPackagePage/components/sidebar-releases-section.tsx +22 -11
- package/src/components/preview/BuildsList.tsx +196 -211
- package/src/components/preview/ConnectedPackagesList.tsx +54 -25
- package/src/components/preview/ConnectedRepoOverview.tsx +63 -35
- package/src/components/preview/{ConnectedRepoDashboard.tsx → PackageReleasesDashboard.tsx} +33 -71
- package/src/components/preview/index.tsx +20 -77
- package/src/hooks/use-package-builds.ts +87 -0
- package/src/hooks/use-package-release-by-id-or-version.ts +36 -0
- package/src/hooks/use-package-release.ts +32 -0
- package/src/lib/utils/isUuid.ts +5 -0
- package/src/pages/preview-build.tsx +3 -3
- package/src/pages/release-builds.tsx +107 -0
- package/src/pages/release-detail.tsx +118 -0
- package/src/pages/releases.tsx +51 -0
- package/src/pages/view-connected-repo.tsx +0 -18
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import { getTestServer } from "bun-tests/fake-snippets-api/fixtures/get-test-server"
|
|
2
|
+
import { test, expect } from "bun:test"
|
|
3
|
+
import defaultAxios from "redaxios"
|
|
4
|
+
|
|
5
|
+
export const createTestPackage = async (axios: typeof defaultAxios) => {
|
|
6
|
+
const packageRes = await axios.post("/api/packages/create", {
|
|
7
|
+
json: {
|
|
8
|
+
name: "test-package",
|
|
9
|
+
description: "Test package for builds",
|
|
10
|
+
},
|
|
11
|
+
})
|
|
12
|
+
return packageRes.data
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const createTestPackageRelease = async (
|
|
16
|
+
axios: typeof defaultAxios,
|
|
17
|
+
packageId: string,
|
|
18
|
+
) => {
|
|
19
|
+
const releaseRes = await axios.post("/api/package_releases/create", {
|
|
20
|
+
package_id: packageId,
|
|
21
|
+
version: "1.0.0",
|
|
22
|
+
is_latest: true,
|
|
23
|
+
})
|
|
24
|
+
return releaseRes.data
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
test("GET /api/package_builds/list - requires package_id or package_release_id", async () => {
|
|
28
|
+
const { jane_axios } = await getTestServer()
|
|
29
|
+
const res = await jane_axios.get("/api/package_builds/list", {
|
|
30
|
+
validateStatus: () => true,
|
|
31
|
+
})
|
|
32
|
+
expect(res.status).toBe(400)
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
test("GET /api/package_builds/list - filters by package_id", async () => {
|
|
36
|
+
const { jane_axios } = await getTestServer()
|
|
37
|
+
const packageRes = await createTestPackage(jane_axios)
|
|
38
|
+
await createTestPackageRelease(jane_axios, packageRes.package.package_id)
|
|
39
|
+
const res = await jane_axios.get(
|
|
40
|
+
`/api/package_builds/list?package_id=${packageRes.package.package_id}`,
|
|
41
|
+
)
|
|
42
|
+
expect(res.status).toBe(200)
|
|
43
|
+
expect(Array.isArray(res.data.package_builds)).toBe(true)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
test("GET /api/package_builds/list - filters by package_release_id", async () => {
|
|
47
|
+
const { jane_axios } = await getTestServer()
|
|
48
|
+
const packageRes = await createTestPackage(jane_axios)
|
|
49
|
+
const { package_release } = await createTestPackageRelease(
|
|
50
|
+
jane_axios,
|
|
51
|
+
packageRes.package.package_id,
|
|
52
|
+
)
|
|
53
|
+
const res = await jane_axios.get(
|
|
54
|
+
`/api/package_builds/list?package_release_id=${package_release.package_release_id}`,
|
|
55
|
+
)
|
|
56
|
+
expect(res.status).toBe(200)
|
|
57
|
+
expect(Array.isArray(res.data.package_builds)).toBe(true)
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
test("GET /api/package_builds/list - returns 404 for non-existent package", async () => {
|
|
61
|
+
const { jane_axios } = await getTestServer()
|
|
62
|
+
const res = await jane_axios.get(
|
|
63
|
+
"/api/package_builds/list?package_id=non-existent-package",
|
|
64
|
+
{ validateStatus: () => true },
|
|
65
|
+
)
|
|
66
|
+
expect(res.status).toBe(404)
|
|
67
|
+
expect(res.data.error.error_code).toBe("package_not_found")
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
test("GET /api/package_builds/list - returns 404 for non-existent package release", async () => {
|
|
71
|
+
const { jane_axios } = await getTestServer()
|
|
72
|
+
const res = await jane_axios.get(
|
|
73
|
+
"/api/package_builds/list?package_release_id=non-existent-package",
|
|
74
|
+
{ validateStatus: () => true },
|
|
75
|
+
)
|
|
76
|
+
expect(res.status).toBe(404)
|
|
77
|
+
expect(res.data.error.error_code).toBe("package_release_not_found")
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
test("GET /api/package_builds/list - returns 403 for unauthorized package access", async () => {
|
|
81
|
+
const { jane_axios, axios } = await getTestServer()
|
|
82
|
+
const packageData = await createTestPackage(jane_axios)
|
|
83
|
+
const res = await axios.get(
|
|
84
|
+
`/api/package_builds/list?package_id=${packageData.package.package_id}`,
|
|
85
|
+
{ validateStatus: () => true },
|
|
86
|
+
)
|
|
87
|
+
expect(res.status).toBe(403)
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
test("GET /api/package_builds/list - returns created builds", async () => {
|
|
91
|
+
const { axios, db } = await getTestServer()
|
|
92
|
+
const { package: pkg } = await createTestPackage(axios)
|
|
93
|
+
const { package_release } = await createTestPackageRelease(
|
|
94
|
+
axios,
|
|
95
|
+
pkg.package_id,
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
db.addPackageBuild({
|
|
99
|
+
package_release_id: package_release.package_release_id,
|
|
100
|
+
created_at: new Date(Date.now() - 1000 * 60 * 30).toISOString(),
|
|
101
|
+
transpilation_in_progress: false,
|
|
102
|
+
transpilation_started_at: new Date(
|
|
103
|
+
Date.now() - 1000 * 60 * 35,
|
|
104
|
+
).toISOString(),
|
|
105
|
+
transpilation_completed_at: new Date(
|
|
106
|
+
Date.now() - 1000 * 60 * 32,
|
|
107
|
+
).toISOString(),
|
|
108
|
+
transpilation_logs: [],
|
|
109
|
+
transpilation_error: null,
|
|
110
|
+
circuit_json_build_in_progress: false,
|
|
111
|
+
circuit_json_build_started_at: new Date(
|
|
112
|
+
Date.now() - 1000 * 60 * 32,
|
|
113
|
+
).toISOString(),
|
|
114
|
+
circuit_json_build_completed_at: new Date(
|
|
115
|
+
Date.now() - 1000 * 60 * 30,
|
|
116
|
+
).toISOString(),
|
|
117
|
+
circuit_json_build_logs: [],
|
|
118
|
+
circuit_json_build_error: null,
|
|
119
|
+
build_in_progress: false,
|
|
120
|
+
build_started_at: new Date(Date.now() - 1000 * 60 * 30).toISOString(),
|
|
121
|
+
build_completed_at: new Date(Date.now() - 1000 * 60 * 25).toISOString(),
|
|
122
|
+
build_error: null,
|
|
123
|
+
build_error_last_updated_at: new Date(
|
|
124
|
+
Date.now() - 1000 * 60 * 25,
|
|
125
|
+
).toISOString(),
|
|
126
|
+
build_logs: null,
|
|
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
|
+
})
|
|
132
|
+
|
|
133
|
+
const res = await axios.get(
|
|
134
|
+
`/api/package_builds/list?package_id=${pkg.package_id}`,
|
|
135
|
+
)
|
|
136
|
+
expect(res.status).toBe(200)
|
|
137
|
+
expect(res.data.package_builds.length).toBe(1)
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
test("GET /api/package_builds/list - sorts builds by created_at descending", async () => {
|
|
141
|
+
const { axios, db } = await getTestServer()
|
|
142
|
+
const { package: pkg } = await createTestPackage(axios)
|
|
143
|
+
const { package_release } = await createTestPackageRelease(
|
|
144
|
+
axios,
|
|
145
|
+
pkg.package_id,
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
db.addPackageBuild({
|
|
149
|
+
package_release_id: package_release.package_release_id,
|
|
150
|
+
created_at: new Date(Date.now() - 1000 * 60 * 30).toISOString(),
|
|
151
|
+
transpilation_in_progress: false,
|
|
152
|
+
transpilation_started_at: new Date(
|
|
153
|
+
Date.now() - 1000 * 60 * 35,
|
|
154
|
+
).toISOString(),
|
|
155
|
+
transpilation_completed_at: new Date(
|
|
156
|
+
Date.now() - 1000 * 60 * 32,
|
|
157
|
+
).toISOString(),
|
|
158
|
+
transpilation_logs: [],
|
|
159
|
+
transpilation_error: null,
|
|
160
|
+
circuit_json_build_in_progress: false,
|
|
161
|
+
circuit_json_build_started_at: new Date(
|
|
162
|
+
Date.now() - 1000 * 60 * 32,
|
|
163
|
+
).toISOString(),
|
|
164
|
+
circuit_json_build_completed_at: new Date(
|
|
165
|
+
Date.now() - 1000 * 60 * 30,
|
|
166
|
+
).toISOString(),
|
|
167
|
+
circuit_json_build_logs: [],
|
|
168
|
+
circuit_json_build_error: null,
|
|
169
|
+
build_in_progress: false,
|
|
170
|
+
build_started_at: new Date(Date.now() - 1000 * 60 * 30).toISOString(),
|
|
171
|
+
build_completed_at: new Date(Date.now() - 1000 * 60 * 25).toISOString(),
|
|
172
|
+
build_error: null,
|
|
173
|
+
build_error_last_updated_at: new Date(
|
|
174
|
+
Date.now() - 1000 * 60 * 25,
|
|
175
|
+
).toISOString(),
|
|
176
|
+
build_logs: null,
|
|
177
|
+
preview_url: "https://preview.tscircuit.com/pb_1",
|
|
178
|
+
branch_name: "main",
|
|
179
|
+
commit_message: "First build",
|
|
180
|
+
commit_author: "john.doe",
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
db.addPackageBuild({
|
|
184
|
+
package_release_id: package_release.package_release_id,
|
|
185
|
+
created_at: new Date(Date.now() - 1000 * 60 * 15).toISOString(),
|
|
186
|
+
transpilation_in_progress: false,
|
|
187
|
+
transpilation_started_at: new Date(
|
|
188
|
+
Date.now() - 1000 * 60 * 20,
|
|
189
|
+
).toISOString(),
|
|
190
|
+
transpilation_completed_at: new Date(
|
|
191
|
+
Date.now() - 1000 * 60 * 17,
|
|
192
|
+
).toISOString(),
|
|
193
|
+
transpilation_logs: [],
|
|
194
|
+
transpilation_error: null,
|
|
195
|
+
circuit_json_build_in_progress: false,
|
|
196
|
+
circuit_json_build_started_at: new Date(
|
|
197
|
+
Date.now() - 1000 * 60 * 17,
|
|
198
|
+
).toISOString(),
|
|
199
|
+
circuit_json_build_completed_at: new Date(
|
|
200
|
+
Date.now() - 1000 * 60 * 15,
|
|
201
|
+
).toISOString(),
|
|
202
|
+
circuit_json_build_logs: [],
|
|
203
|
+
circuit_json_build_error: null,
|
|
204
|
+
build_in_progress: false,
|
|
205
|
+
build_started_at: new Date(Date.now() - 1000 * 60 * 15).toISOString(),
|
|
206
|
+
build_completed_at: new Date(Date.now() - 1000 * 60 * 10).toISOString(),
|
|
207
|
+
build_error: null,
|
|
208
|
+
build_error_last_updated_at: new Date(
|
|
209
|
+
Date.now() - 1000 * 60 * 10,
|
|
210
|
+
).toISOString(),
|
|
211
|
+
build_logs: null,
|
|
212
|
+
preview_url: "https://preview.tscircuit.com/pb_2",
|
|
213
|
+
branch_name: "main",
|
|
214
|
+
commit_message: "Second build",
|
|
215
|
+
commit_author: "john.doe",
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
const res = await axios.get(
|
|
219
|
+
`/api/package_builds/list?package_id=${pkg.package_id}`,
|
|
220
|
+
)
|
|
221
|
+
expect(res.status).toBe(200)
|
|
222
|
+
expect(Array.isArray(res.data.package_builds)).toBe(true)
|
|
223
|
+
expect(res.data.package_builds.length).toBe(2)
|
|
224
|
+
|
|
225
|
+
const builds = res.data.package_builds
|
|
226
|
+
for (let i = 1; i < builds.length; i++) {
|
|
227
|
+
const prevBuild = new Date(builds[i - 1].created_at)
|
|
228
|
+
const currentBuild = new Date(builds[i].created_at)
|
|
229
|
+
expect(prevBuild.getTime()).toBeGreaterThanOrEqual(currentBuild.getTime())
|
|
230
|
+
}
|
|
231
|
+
})
|
|
232
|
+
|
|
233
|
+
test("GET /api/package_builds/list - handles both package_id and package_release_id (package_release_id takes precedence)", async () => {
|
|
234
|
+
const { jane_axios } = await getTestServer()
|
|
235
|
+
const packageRes = await createTestPackage(jane_axios)
|
|
236
|
+
const { package_release } = await createTestPackageRelease(
|
|
237
|
+
jane_axios,
|
|
238
|
+
packageRes.package.package_id,
|
|
239
|
+
)
|
|
240
|
+
const res = await jane_axios.get(
|
|
241
|
+
`/api/package_builds/list?package_id=${packageRes.package.package_id}&package_release_id=${package_release.package_release_id}`,
|
|
242
|
+
)
|
|
243
|
+
expect(res.status).toBe(200)
|
|
244
|
+
expect(Array.isArray(res.data.package_builds)).toBe(true)
|
|
245
|
+
})
|
|
246
|
+
|
|
247
|
+
test("GET /api/package_builds/list - returns created builds with logs or not", async () => {
|
|
248
|
+
const { axios, db } = await getTestServer()
|
|
249
|
+
const { package: pkg } = await createTestPackage(axios)
|
|
250
|
+
const { package_release } = await createTestPackageRelease(
|
|
251
|
+
axios,
|
|
252
|
+
pkg.package_id,
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
const buildLogs = ["Started build", "Building components", "Build completed"]
|
|
256
|
+
const transpilationLogs = ["Transpiling files", "Transpilation done"]
|
|
257
|
+
const circuitJsonBuildLogs = ["Generating circuit JSON", "Circuit JSON ready"]
|
|
258
|
+
|
|
259
|
+
await db.addPackageBuild({
|
|
260
|
+
package_release_id: package_release.package_release_id,
|
|
261
|
+
created_at: new Date(Date.now() - 1000 * 60 * 30).toISOString(),
|
|
262
|
+
transpilation_in_progress: false,
|
|
263
|
+
transpilation_started_at: new Date(
|
|
264
|
+
Date.now() - 1000 * 60 * 35,
|
|
265
|
+
).toISOString(),
|
|
266
|
+
transpilation_completed_at: new Date(
|
|
267
|
+
Date.now() - 1000 * 60 * 32,
|
|
268
|
+
).toISOString(),
|
|
269
|
+
transpilation_logs: transpilationLogs,
|
|
270
|
+
transpilation_error: null,
|
|
271
|
+
circuit_json_build_in_progress: false,
|
|
272
|
+
circuit_json_build_started_at: new Date(
|
|
273
|
+
Date.now() - 1000 * 60 * 32,
|
|
274
|
+
).toISOString(),
|
|
275
|
+
circuit_json_build_completed_at: new Date(
|
|
276
|
+
Date.now() - 1000 * 60 * 30,
|
|
277
|
+
).toISOString(),
|
|
278
|
+
circuit_json_build_logs: circuitJsonBuildLogs,
|
|
279
|
+
circuit_json_build_error: null,
|
|
280
|
+
build_in_progress: false,
|
|
281
|
+
build_started_at: new Date(Date.now() - 1000 * 60 * 30).toISOString(),
|
|
282
|
+
build_completed_at: new Date(Date.now() - 1000 * 60 * 25).toISOString(),
|
|
283
|
+
build_error: null,
|
|
284
|
+
build_error_last_updated_at: new Date(
|
|
285
|
+
Date.now() - 1000 * 60 * 25,
|
|
286
|
+
).toISOString(),
|
|
287
|
+
build_logs: buildLogs.join(" "),
|
|
288
|
+
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
|
+
})
|
|
293
|
+
|
|
294
|
+
const resWithoutLogs = await axios.get(
|
|
295
|
+
`/api/package_builds/list?package_id=${pkg.package_id}`,
|
|
296
|
+
)
|
|
297
|
+
expect(resWithoutLogs.status).toBe(200)
|
|
298
|
+
expect(resWithoutLogs.data.package_builds.length).toBe(1)
|
|
299
|
+
expect(resWithoutLogs.data.package_builds[0].build_logs).toBeNull()
|
|
300
|
+
expect(resWithoutLogs.data.package_builds[0].transpilation_logs).toEqual([])
|
|
301
|
+
expect(resWithoutLogs.data.package_builds[0].circuit_json_build_logs).toEqual(
|
|
302
|
+
[],
|
|
303
|
+
)
|
|
304
|
+
})
|