@tscircuit/fake-snippets 0.0.6 → 0.0.8

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.
Files changed (45) hide show
  1. package/bun-tests/fake-snippets-api/fixtures/get-test-server.ts +2 -5
  2. package/bun-tests/fake-snippets-api/routes/package_files/create.test.ts +375 -0
  3. package/bun-tests/fake-snippets-api/routes/package_files/download.test.ts +248 -0
  4. package/bun-tests/fake-snippets-api/routes/package_files/get.test.ts +220 -0
  5. package/bun-tests/fake-snippets-api/routes/package_files/list.test.ts +204 -0
  6. package/bun-tests/fake-snippets-api/routes/package_releases/get.test.ts +0 -1
  7. package/bun-tests/fake-snippets-api/routes/packages/{list.test.ts → list-1.test.ts} +3 -55
  8. package/bun-tests/fake-snippets-api/routes/packages/list-2.test.ts +59 -0
  9. package/bun-tests/fake-snippets-api/routes/snippets/create.test.ts +34 -1
  10. package/bun.lock +100 -73
  11. package/dist/bundle.js +729 -273
  12. package/fake-snippets-api/lib/db/db-client.ts +58 -50
  13. package/fake-snippets-api/lib/db/schema.ts +15 -6
  14. package/fake-snippets-api/lib/package_file/get-package-file-id-from-file-descriptor.ts +168 -0
  15. package/fake-snippets-api/lib/package_release/find-package-release-id.ts +122 -0
  16. package/fake-snippets-api/lib/public-mapping/public-map-package.ts +9 -2
  17. package/fake-snippets-api/routes/api/package_files/create.ts +132 -0
  18. package/fake-snippets-api/routes/api/package_files/download.ts +70 -153
  19. package/fake-snippets-api/routes/api/package_files/get.ts +24 -5
  20. package/fake-snippets-api/routes/api/package_files/list.ts +16 -28
  21. package/fake-snippets-api/routes/api/snippets/create.ts +123 -29
  22. package/index.html +12 -1
  23. package/package.json +10 -9
  24. package/playwright-tests/profile-page.spec.ts +59 -0
  25. package/playwright-tests/snapshots/profile-page.spec.ts-profile-page-before-delete.png +0 -0
  26. package/playwright-tests/snapshots/profile-page.spec.ts-profile-page-delete-dialog.png +0 -0
  27. package/playwright-tests/snapshots/profile-page.spec.ts-profile-page-dropdown-open.png +0 -0
  28. package/scripts/generate-image-sizes.ts +0 -1
  29. package/scripts/generate_bundle_stats.js +22 -6
  30. package/src/components/AiChatInterface.tsx +8 -0
  31. package/src/components/Analytics.tsx +1 -1
  32. package/src/components/CodeAndPreview.tsx +9 -3
  33. package/src/components/CreateNewSnippetWithAiHero.tsx +6 -2
  34. package/src/components/EditorNav.tsx +4 -0
  35. package/src/components/Footer.tsx +1 -1
  36. package/src/components/Header.tsx +7 -10
  37. package/src/components/HeaderLogin.tsx +1 -1
  38. package/src/components/PreviewContent.tsx +4 -1
  39. package/src/components/SnippetList.tsx +71 -0
  40. package/src/lib/templates/blinking-led-board-template.ts +2 -1
  41. package/src/pages/dashboard.tsx +19 -44
  42. package/src/pages/editor.tsx +1 -1
  43. package/src/pages/landing.tsx +8 -16
  44. package/src/pages/quickstart.tsx +9 -9
  45. package/src/pages/user-profile.tsx +50 -3
@@ -0,0 +1,132 @@
1
+ import * as zt from "fake-snippets-api/lib/db/schema"
2
+ import { findPackageReleaseId } from "fake-snippets-api/lib/package_release/find-package-release-id"
3
+ import { withRouteSpec } from "fake-snippets-api/lib/with-winter-spec"
4
+ import { z } from "zod"
5
+
6
+ const routeSpec = {
7
+ methods: ["POST"],
8
+ auth: "none",
9
+ jsonBody: z
10
+ .object({
11
+ file_path: z.string(),
12
+ is_release_tarball: z.boolean().optional().default(false),
13
+ content_mimetype: z.string().optional(),
14
+ content_text: z.string().optional(),
15
+ content_base64: z.string().optional(),
16
+ package_release_id: z.string().optional(),
17
+ package_name_with_version: z.string().optional(),
18
+ npm_pack_output: z.any().optional(),
19
+ })
20
+ .refine((v) => {
21
+ if (v.package_release_id) return true
22
+ if (v.package_name_with_version) return true
23
+ return false
24
+ }, "Must specify either package_release_id or package_name_with_version")
25
+ .refine((v) => {
26
+ if (v.package_release_id && v.package_name_with_version) return false
27
+ return true
28
+ }, "Cannot specify both package_release_id and package_name_with_version")
29
+ .refine((v) => {
30
+ if (v.content_base64 && v.content_text) return false
31
+ if (!v.content_base64 && !v.content_text) return false
32
+ return true
33
+ }, "Either content_base64 or content_text is required"),
34
+ jsonResponse: z.object({
35
+ ok: z.boolean(),
36
+ package_file: zt.packageFileSchema,
37
+ }),
38
+ } as const
39
+
40
+ export default withRouteSpec(routeSpec)(async (req, ctx) => {
41
+ const {
42
+ file_path,
43
+ content_mimetype: providedContentMimetype,
44
+ content_base64,
45
+ content_text,
46
+ is_release_tarball,
47
+ npm_pack_output,
48
+ } = req.jsonBody
49
+
50
+ if (is_release_tarball && !npm_pack_output) {
51
+ return ctx.error(400, {
52
+ error_code: "missing_options",
53
+ message: "npm_pack_output is required for release tarballs",
54
+ })
55
+ }
56
+
57
+ if (!is_release_tarball && npm_pack_output) {
58
+ return ctx.error(404, {
59
+ error_code: "invalid_options",
60
+ message: "npm_pack_output is only valid for release tarballs",
61
+ })
62
+ }
63
+
64
+ let packageReleaseId = req.jsonBody.package_release_id
65
+
66
+ if (!packageReleaseId && req.jsonBody.package_name_with_version) {
67
+ const foundPackageReleaseId = await findPackageReleaseId(
68
+ req.jsonBody.package_name_with_version,
69
+ ctx,
70
+ )
71
+ if (foundPackageReleaseId) {
72
+ packageReleaseId = foundPackageReleaseId
73
+ }
74
+ }
75
+
76
+ if (!packageReleaseId) {
77
+ return ctx.error(404, {
78
+ error_code: "package_release_not_found",
79
+ message: "Package release not found",
80
+ })
81
+ }
82
+
83
+ // Verify the package release exists
84
+ const packageRelease = ctx.db.packageReleases.find(
85
+ (pr) => pr.package_release_id === packageReleaseId,
86
+ )
87
+
88
+ if (!packageRelease) {
89
+ return ctx.error(404, {
90
+ error_code: "package_release_not_found",
91
+ message: "Package release not found",
92
+ })
93
+ }
94
+
95
+ // Determine content mimetype
96
+ const contentMimetype =
97
+ providedContentMimetype ||
98
+ (file_path.endsWith(".ts") || file_path.endsWith(".tsx")
99
+ ? "text/typescript"
100
+ : null) ||
101
+ (file_path.endsWith(".js") ? "application/javascript" : null) ||
102
+ (file_path.endsWith(".json") ? "application/json" : null) ||
103
+ (file_path.endsWith(".md") ? "text/markdown" : null) ||
104
+ (file_path.endsWith(".html") ? "text/html" : null) ||
105
+ (file_path.endsWith(".css") ? "text/css" : null) ||
106
+ "application/octet-stream"
107
+
108
+ // Create the package file
109
+ const newPackageFile = {
110
+ package_file_id: crypto.randomUUID(),
111
+ package_release_id: packageReleaseId,
112
+ file_path,
113
+ content_text:
114
+ content_text ||
115
+ (content_base64
116
+ ? Buffer.from(content_base64, "base64").toString()
117
+ : null),
118
+ content_mimetype: contentMimetype,
119
+ is_directory: false,
120
+ is_release_tarball: is_release_tarball || false,
121
+ npm_pack_output: npm_pack_output || null,
122
+ created_at: new Date().toISOString(),
123
+ }
124
+
125
+ // Add to the test database
126
+ ctx.db.addPackageFile(newPackageFile)
127
+
128
+ return ctx.json({
129
+ ok: true,
130
+ package_file: newPackageFile,
131
+ })
132
+ })
@@ -1,170 +1,87 @@
1
+ import { getPackageFileIdFromFileDescriptor } from "fake-snippets-api/lib/package_file/get-package-file-id-from-file-descriptor"
2
+ import { findPackageReleaseId } from "fake-snippets-api/lib/package_release/find-package-release-id"
1
3
  import { withRouteSpec } from "fake-snippets-api/lib/with-winter-spec"
2
4
  import { z } from "zod"
3
5
 
4
- export default withRouteSpec({
5
- methods: ["GET"],
6
+ const routeSpec = {
7
+ methods: ["GET", "POST"],
6
8
  auth: "none",
7
- queryParams: z.object({
8
- jsdelivr_resolve: z
9
- .enum(["true", "false"])
10
- .optional()
11
- .transform((v) => v === "true"),
12
- jsdelivr_path: z.string(),
13
- }),
14
- jsonResponse: z.any(),
15
- })(async (req, ctx) => {
16
- const { jsdelivr_path, jsdelivr_resolve } = req.query
17
-
18
- // Parse the file path
19
- const [owner, packageWithVersion, ...rest] = jsdelivr_path.split("/")
20
- if (!packageWithVersion) {
21
- return ctx.error(400, {
22
- error_code: "invalid_path",
23
- message: "Invalid path",
9
+ queryParams: z
10
+ .object({
11
+ package_file_id: z.string(),
24
12
  })
25
- }
26
- const [packageName, version] = packageWithVersion.split("@")
27
- const fileName = rest.join("/")
13
+ .or(
14
+ z.object({
15
+ package_name_with_version: z.string(),
16
+ file_path: z.string(),
17
+ }),
18
+ ),
19
+ jsonResponse: z.any(), // Using any because we're returning binary data
20
+ } as const
28
21
 
29
- // Find the snippet
30
- // const snippet =
22
+ export default withRouteSpec(routeSpec)(async (req, ctx) => {
23
+ let packageFileId: string | undefined
24
+ const params = req.query
31
25
 
32
- // if (!snippet) {
33
- // return ctx.error(404, {
34
- // error_code: "snippet_not_found",
35
- // message: "Snippet not found",
36
- // })
37
- // }
26
+ if ("package_file_id" in params) {
27
+ packageFileId = params.package_file_id
28
+ } else if ("package_name_with_version" in params) {
29
+ const { package_name_with_version, file_path } = params
38
30
 
39
- // if (!fileName && !jsdelivr_resolve) {
40
- // return new Response(
41
- // JSON.stringify({
42
- // tags: {
43
- // latest: "0.0.1",
44
- // },
45
- // versions: ["0.0.1"],
46
- // }),
47
- // {
48
- // status: 200,
49
- // headers: { "Content-Type": "application/json" },
50
- // },
51
- // )
52
- // }
31
+ const packageReleaseId = await findPackageReleaseId(
32
+ package_name_with_version,
33
+ ctx,
34
+ )
53
35
 
54
- // if (!fileName && jsdelivr_resolve) {
55
- // return new Response(
56
- // JSON.stringify({
57
- // version: "0.0.1",
58
- // }),
59
- // {
60
- // status: 200,
61
- // headers: { "Content-Type": "application/json" },
62
- // },
63
- // )
64
- // }
36
+ if (!packageReleaseId) {
37
+ return ctx.error(404, {
38
+ error_code: "not_found",
39
+ message: "Package release not found",
40
+ })
41
+ }
65
42
 
66
- // const latestRelease = await ctx.db
67
- // .selectFrom("main.package_release")
68
- // .where("package_id", "=", snippet.snippet_id)
69
- // .where("is_latest", "=", true)
70
- // .selectAll()
71
- // .executeTakeFirst()
72
-
73
- // const dtsFile = await ctx.db
74
- // .selectFrom("main.package_file")
75
- // .where("package_release_id", "=", latestRelease!.package_release_id)
76
- // .where("file_path", "=", "/dist/index.d.ts")
77
- // .select("content_text")
78
- // .executeTakeFirst()
43
+ try {
44
+ packageFileId = await getPackageFileIdFromFileDescriptor(
45
+ {
46
+ package_release_id: packageReleaseId,
47
+ file_path: file_path,
48
+ },
49
+ ctx,
50
+ )
51
+ } catch (error) {
52
+ return ctx.error(404, {
53
+ error_code: "not_found",
54
+ message: "Package file not found",
55
+ })
56
+ }
57
+ }
79
58
 
80
- // // If no fileName is provided, return the directory listing
81
- // if (!fileName || fileName === "flat") {
82
- // const files = [
83
- // {
84
- // type: "file",
85
- // name: "index.ts",
86
- // hash: "placeholder_hash",
87
- // time: snippet.updated_at,
88
- // size: snippet.code?.length ?? 0,
89
- // },
90
- // {
91
- // type: "file",
92
- // name: "index.d.ts",
93
- // hash: "placeholder_hash",
94
- // time: snippet.updated_at,
95
- // size: dtsFile?.content_text?.length ?? 0,
96
- // },
97
- // {
98
- // type: "file",
99
- // name: "package.json",
100
- // hash: "placeholder_hash",
101
- // time: snippet.updated_at,
102
- // size: JSON.stringify({
103
- // name: `@tsci/${owner}.${packageName}`,
104
- // version: version || "0.0.1",
105
- // main: "index.ts",
106
- // types: "index.d.ts",
107
- // }).length,
108
- // },
109
- // ]
59
+ if (!packageFileId) {
60
+ return ctx.error(400, {
61
+ error_code: "bad_request",
62
+ message: "Could not determine package_file_id",
63
+ })
64
+ }
110
65
 
111
- // const response = {
112
- // default: "/index.ts",
113
- // files:
114
- // fileName === "flat"
115
- // ? files.map((f) => ({
116
- // name: `/${f.name}`,
117
- // hash: f.hash,
118
- // time: f.time,
119
- // size: f.size,
120
- // }))
121
- // : [
122
- // {
123
- // type: "directory",
124
- // name: ".",
125
- // files: files,
126
- // },
127
- // ],
128
- // }
66
+ const packageFile = ctx.db.packageFiles.find(
67
+ (pf) => pf.package_file_id === packageFileId,
68
+ )
129
69
 
130
- // return new Response(JSON.stringify(response, null, 2), {
131
- // status: 200,
132
- // headers: { "Content-Type": "application/json" },
133
- // })
134
- // }
70
+ if (!packageFile) {
71
+ return ctx.error(404, {
72
+ error_code: "not_found",
73
+ message: "Package file not found",
74
+ })
75
+ }
135
76
 
136
- // // Handle file downloads
137
- // let content: string
138
- // switch (fileName) {
139
- // case "index.ts":
140
- // content = snippet.code ?? ""
141
- // break
142
- // case "index.d.ts":
143
- // content = dtsFile?.content_text ?? ""
144
- // break
145
- // case "package.json":
146
- // content = JSON.stringify(
147
- // {
148
- // name: `@tsci/${owner}.${packageName}`,
149
- // version: version || "0.0.1",
150
- // main: "index.ts",
151
- // types: "index.d.ts",
152
- // },
153
- // null,
154
- // 2,
155
- // )
156
- // break
157
- // default:
158
- // return ctx.error(404, {
159
- // error_code: "file_not_found",
160
- // message: "Requested file not found",
161
- // })
162
- // }
77
+ const contentType = "text/plain"
163
78
 
164
- const content = "TODO"
79
+ const headers = {
80
+ "Content-Type": contentType,
81
+ "Content-Disposition": `attachment; filename="${packageFile.file_path.split("/").pop()}"`,
82
+ "Cache-Control": "public, max-age=86400, stale-while-revalidate=604800",
83
+ Expires: new Date(Date.now() + 86400000).toUTCString(),
84
+ }
165
85
 
166
- return new Response(content, {
167
- status: 200,
168
- headers: { "Content-Type": "text/plain" },
169
- })
86
+ return new Response(packageFile.content_text, { headers })
170
87
  })
@@ -1,24 +1,24 @@
1
1
  import { withRouteSpec } from "fake-snippets-api/lib/with-winter-spec"
2
2
  import { z } from "zod"
3
3
  import * as ZT from "fake-snippets-api/lib/db/schema"
4
- import { NotFoundError } from "winterspec/middleware"
4
+ import { getPackageFileIdFromFileDescriptor } from "fake-snippets-api/lib/package_file/get-package-file-id-from-file-descriptor"
5
5
 
6
6
  const routeSpec = {
7
7
  methods: ["POST"],
8
8
  auth: "none",
9
9
  jsonBody: z
10
10
  .object({
11
- package_file_id: z.string().uuid(),
11
+ package_file_id: z.string(),
12
12
  })
13
13
  .or(
14
14
  z.object({
15
- package_release_id: z.string().uuid(),
15
+ package_release_id: z.string(),
16
16
  file_path: z.string(),
17
17
  }),
18
18
  )
19
19
  .or(
20
20
  z.object({
21
- package_id: z.string().uuid(),
21
+ package_id: z.string(),
22
22
  version: z.string().optional(),
23
23
  file_path: z.string(),
24
24
  }),
@@ -45,8 +45,27 @@ const routeSpec = {
45
45
  } as const
46
46
 
47
47
  export default withRouteSpec(routeSpec)(async (req, ctx) => {
48
+ const packageFileId = await getPackageFileIdFromFileDescriptor(
49
+ req.jsonBody,
50
+ ctx,
51
+ )
52
+
53
+ const packageFile = ctx.db.packageFiles.find(
54
+ (pf: ZT.PackageFile) => pf.package_file_id === packageFileId,
55
+ )
56
+
57
+ if (!packageFile) {
58
+ return ctx.error(404, {
59
+ error_code: "package_file_not_found",
60
+ message: "Package file not found",
61
+ })
62
+ }
63
+
48
64
  return ctx.json({
49
65
  ok: true,
50
- package_file: undefined,
66
+ package_file: {
67
+ ...packageFile,
68
+ created_at: packageFile.created_at.toString(),
69
+ },
51
70
  })
52
71
  })
@@ -1,13 +1,14 @@
1
1
  import { withRouteSpec } from "fake-snippets-api/lib/with-winter-spec"
2
2
  import { z } from "zod"
3
3
  import * as ZT from "fake-snippets-api/lib/db/schema"
4
+ import { findPackageReleaseId } from "fake-snippets-api/lib/package_release/find-package-release-id"
4
5
 
5
6
  const routeSpec = {
6
7
  methods: ["POST"],
7
8
  auth: "none",
8
9
  jsonBody: z
9
10
  .object({
10
- package_release_id: z.string().uuid(),
11
+ package_release_id: z.string(),
11
12
  })
12
13
  .or(
13
14
  z.object({
@@ -27,34 +28,21 @@ const routeSpec = {
27
28
  } as const
28
29
 
29
30
  export default withRouteSpec(routeSpec)(async (req, ctx) => {
30
- // const package_release_id = await findPackageReleaseId(req.jsonBody, ctx)
31
- // if (!package_release_id) {
32
- // return ctx.error(404, {
33
- // error_code: "package_release_not_found",
34
- // message: "Package release not found",
35
- // })
36
- // }
37
- // const package_files = await ctx.db
38
- // .selectFrom("main.package_file")
39
- // .select([
40
- // "package_file_id",
41
- // "package_release_id",
42
- // "content_mimetype",
43
- // "file_path",
44
- // "created_at",
45
- // ])
46
- // .where("package_release_id", "=", package_release_id)
47
- // .where("file_path", "not like", ".tscircuit-internal/%")
48
- // .execute()
49
- // return ctx.json({
50
- // ok: true,
51
- // package_files: package_files.map((pf) => ({
52
- // ...pf,
53
- // created_at: pf.created_at.toISOString(),
54
- // })),
55
- // })
31
+ const packageReleaseId = await findPackageReleaseId(req.jsonBody, ctx)
32
+
33
+ if (!packageReleaseId) {
34
+ return ctx.error(404, {
35
+ error_code: "package_release_not_found",
36
+ message: "Package release not found",
37
+ })
38
+ }
39
+
40
+ const packageFiles = ctx.db.packageFiles.filter(
41
+ (file) => file.package_release_id === packageReleaseId,
42
+ )
43
+
56
44
  return ctx.json({
57
45
  ok: true,
58
- package_files: [],
46
+ package_files: packageFiles,
59
47
  })
60
48
  })
@@ -30,50 +30,144 @@ export default withRouteSpec({
30
30
  } = req.jsonBody
31
31
 
32
32
  if (!unscoped_name) {
33
- unscoped_name = `untitled-${snippet_type}-${ctx.db.idCounter + 1}`
33
+ // Count snippets of this type for this user
34
+ const userSnippets = ctx.db.packages.filter(
35
+ (p) =>
36
+ p.owner_github_username === ctx.auth.github_username &&
37
+ p.is_snippet === true &&
38
+ ((p.is_board && snippet_type === "board") ||
39
+ (p.is_package && snippet_type === "package") ||
40
+ (p.is_model && snippet_type === "model") ||
41
+ (p.is_footprint && snippet_type === "footprint")),
42
+ )
43
+ unscoped_name = `untitled-${snippet_type}-${userSnippets.length + 1}`
34
44
  }
35
45
 
36
- const existingSnippet = ctx.db.snippets.find(
37
- (snippet) =>
38
- snippet.unscoped_name === unscoped_name &&
39
- snippet.owner_name === ctx.auth.github_username,
46
+ const existingPackage = ctx.db.packages.find(
47
+ (pkg) =>
48
+ pkg.unscoped_name === unscoped_name &&
49
+ pkg.owner_github_username === ctx.auth.github_username,
40
50
  )
41
51
 
42
- if (existingSnippet) {
52
+ if (existingPackage) {
43
53
  return ctx.error(400, {
44
54
  error_code: "snippet_already_exists",
45
55
  message: "You have already forked this snippet in your account.",
46
56
  })
47
57
  }
48
58
 
49
- let newSnippet: Omit<
50
- z.input<typeof snippetSchema>,
51
- "snippet_id" | "package_release_id"
52
- > = {
53
- name: `${ctx.auth.github_username}/${unscoped_name}`,
54
- unscoped_name,
55
- owner_name: ctx.auth.github_username,
56
- code,
57
- created_at: new Date().toISOString(),
58
- updated_at: new Date().toISOString(),
59
- snippet_type,
60
- description,
61
- compiled_js,
62
- circuit_json,
63
- dts,
64
- }
65
-
66
59
  try {
67
- newSnippet = ctx.db.addSnippet(newSnippet)
60
+ // Create the package directly (which will serve as our snippet)
61
+ const newPackage = {
62
+ package_id: `pkg_${Date.now()}`,
63
+ creator_account_id: ctx.auth.account_id,
64
+ owner_org_id: ctx.auth.personal_org_id,
65
+ owner_github_username: ctx.auth.github_username,
66
+ is_source_from_github: false,
67
+ description: description,
68
+ name: `${ctx.auth.github_username}/${unscoped_name}`,
69
+ unscoped_name: unscoped_name,
70
+ latest_version: "0.0.1",
71
+ license: null,
72
+ star_count: 0,
73
+ created_at: new Date().toISOString(),
74
+ updated_at: new Date().toISOString(),
75
+ ai_description: null,
76
+ is_snippet: true,
77
+ is_board: snippet_type === "board",
78
+ is_package: snippet_type === "package",
79
+ is_model: snippet_type === "model",
80
+ is_footprint: snippet_type === "footprint",
81
+ snippet_type: snippet_type,
82
+ is_private: false,
83
+ is_public: true,
84
+ is_unlisted: false,
85
+ latest_package_release_id: "",
86
+ }
87
+
88
+ ctx.db.addPackage(newPackage)
89
+
90
+ const newPackageRelease = {
91
+ package_release_id: `package_release_${Date.now()}`,
92
+ package_id: newPackage.package_id,
93
+ version: "0.0.1",
94
+ is_latest: true,
95
+ is_locked: false,
96
+ created_at: newPackage.created_at,
97
+ }
98
+
99
+ ctx.db.addPackageRelease(newPackageRelease)
100
+
101
+ // Update the package with the release ID
102
+ newPackage.latest_package_release_id = newPackageRelease.package_release_id
103
+
104
+ // Add package files
105
+ // Add index.tsx file with the code content
106
+ ctx.db.addPackageFile({
107
+ package_release_id: newPackageRelease.package_release_id,
108
+ file_path: "index.tsx",
109
+ content_text: code,
110
+ created_at: new Date().toISOString(),
111
+ })
112
+
113
+ // Add DTS file if provided
114
+ if (dts) {
115
+ ctx.db.addPackageFile({
116
+ package_release_id: newPackageRelease.package_release_id,
117
+ file_path: "/dist/index.d.ts",
118
+ content_text: dts,
119
+ created_at: new Date().toISOString(),
120
+ })
121
+ }
122
+
123
+ // Add compiled JS if provided
124
+ if (compiled_js) {
125
+ ctx.db.addPackageFile({
126
+ package_release_id: newPackageRelease.package_release_id,
127
+ file_path: "/dist/index.js",
128
+ content_text: compiled_js,
129
+ created_at: new Date().toISOString(),
130
+ })
131
+ }
132
+
133
+ // Add circuit JSON if provided
134
+ if (circuit_json) {
135
+ ctx.db.addPackageFile({
136
+ package_release_id: newPackageRelease.package_release_id,
137
+ file_path: "/dist/circuit.json",
138
+ content_text: JSON.stringify(circuit_json),
139
+ created_at: new Date().toISOString(),
140
+ })
141
+ }
142
+
143
+ // Create the snippet response object
144
+ const snippetResponse = {
145
+ snippet_id: newPackage.package_id,
146
+ package_release_id: newPackageRelease.package_release_id,
147
+ name: newPackage.name,
148
+ unscoped_name: newPackage.unscoped_name,
149
+ owner_name: ctx.auth.github_username,
150
+ code,
151
+ dts,
152
+ compiled_js,
153
+ star_count: 0,
154
+ created_at: newPackage.created_at,
155
+ updated_at: newPackage.updated_at,
156
+ snippet_type: snippet_type,
157
+ circuit_json: circuit_json,
158
+ description: description,
159
+ is_starred: false,
160
+ version: "0.0.1",
161
+ }
162
+
163
+ return ctx.json({
164
+ ok: true,
165
+ snippet: snippetResponse,
166
+ })
68
167
  } catch (error) {
69
168
  return ctx.error(500, {
70
169
  error_code: "snippet_creation_failed",
71
170
  message: `Failed to create snippet: ${error}`,
72
171
  })
73
172
  }
74
-
75
- return ctx.json({
76
- ok: true,
77
- snippet: newSnippet as any,
78
- })
79
173
  })