@tscircuit/fake-snippets 0.0.6 → 0.0.7

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 (38) hide show
  1. package/bun-tests/fake-snippets-api/routes/package_files/create.test.ts +375 -0
  2. package/bun-tests/fake-snippets-api/routes/package_files/download.test.ts +248 -0
  3. package/bun-tests/fake-snippets-api/routes/package_files/get.test.ts +220 -0
  4. package/bun-tests/fake-snippets-api/routes/package_files/list.test.ts +204 -0
  5. package/bun-tests/fake-snippets-api/routes/package_releases/get.test.ts +0 -1
  6. package/bun.lock +97 -73
  7. package/dist/bundle.js +584 -212
  8. package/fake-snippets-api/lib/db/db-client.ts +13 -0
  9. package/fake-snippets-api/lib/package_file/get-package-file-id-from-file-descriptor.ts +168 -0
  10. package/fake-snippets-api/lib/package_release/find-package-release-id.ts +122 -0
  11. package/fake-snippets-api/routes/api/package_files/create.ts +132 -0
  12. package/fake-snippets-api/routes/api/package_files/download.ts +70 -153
  13. package/fake-snippets-api/routes/api/package_files/get.ts +24 -5
  14. package/fake-snippets-api/routes/api/package_files/list.ts +16 -28
  15. package/index.html +12 -1
  16. package/package.json +9 -9
  17. package/playwright-tests/profile-page.spec.ts +59 -0
  18. package/playwright-tests/snapshots/profile-page.spec.ts-profile-page-before-delete.png +0 -0
  19. package/playwright-tests/snapshots/profile-page.spec.ts-profile-page-delete-dialog.png +0 -0
  20. package/playwright-tests/snapshots/profile-page.spec.ts-profile-page-dropdown-open.png +0 -0
  21. package/scripts/generate-image-sizes.ts +0 -1
  22. package/scripts/generate_bundle_stats.js +22 -6
  23. package/src/components/AiChatInterface.tsx +8 -0
  24. package/src/components/Analytics.tsx +1 -1
  25. package/src/components/CodeAndPreview.tsx +9 -3
  26. package/src/components/CreateNewSnippetWithAiHero.tsx +6 -2
  27. package/src/components/EditorNav.tsx +4 -0
  28. package/src/components/Footer.tsx +1 -1
  29. package/src/components/Header.tsx +7 -10
  30. package/src/components/HeaderLogin.tsx +1 -1
  31. package/src/components/PreviewContent.tsx +4 -1
  32. package/src/components/SnippetList.tsx +71 -0
  33. package/src/lib/templates/blinking-led-board-template.ts +2 -1
  34. package/src/pages/dashboard.tsx +19 -44
  35. package/src/pages/editor.tsx +1 -1
  36. package/src/pages/landing.tsx +8 -16
  37. package/src/pages/quickstart.tsx +9 -9
  38. package/src/pages/user-profile.tsx +50 -3
@@ -18,6 +18,7 @@ import {
18
18
  packageSchema,
19
19
  Package,
20
20
  PackageRelease,
21
+ PackageFile,
21
22
  } from "./schema.ts"
22
23
  import { combine } from "zustand/middleware"
23
24
  import { seed as seedFn } from "./seed"
@@ -417,4 +418,16 @@ const initializer = combine(databaseSchema.parse({}), (set, get) => ({
417
418
  ),
418
419
  }))
419
420
  },
421
+ addPackageFile: (
422
+ packageFile: Omit<PackageFile, "package_file_id">,
423
+ ): PackageFile => {
424
+ const newPackageFile = {
425
+ package_file_id: `package_file_${Date.now()}`,
426
+ ...packageFile,
427
+ }
428
+ set((state) => ({
429
+ packageFiles: [...state.packageFiles, newPackageFile],
430
+ }))
431
+ return newPackageFile
432
+ },
420
433
  }))
@@ -0,0 +1,168 @@
1
+ import { NotFoundError } from "winterspec/middleware"
2
+ import * as ZT from "../db/schema"
3
+ export const getPackageFileIdFromFileDescriptor = async (
4
+ descriptor:
5
+ | { package_file_id: string }
6
+ | { package_release_id: string; file_path: string }
7
+ | { package_id: string; version?: string; file_path: string }
8
+ | { package_name: string; version?: string; file_path: string }
9
+ | { package_name_with_version: string; file_path: string },
10
+ ctx: { db: any },
11
+ ): Promise<string> => {
12
+ if ("package_file_id" in descriptor) {
13
+ const packageFile = ctx.db.packageFiles.find(
14
+ (pf: ZT.PackageFile) => pf.package_file_id === descriptor.package_file_id,
15
+ )
16
+
17
+ if (!packageFile) {
18
+ throw new NotFoundError("Package file not found")
19
+ }
20
+
21
+ return descriptor.package_file_id
22
+ }
23
+
24
+ if ("package_release_id" in descriptor) {
25
+ const { package_release_id, file_path } = descriptor
26
+ const packageFile = ctx.db.packageFiles.find(
27
+ (pf: ZT.PackageFile) =>
28
+ pf.package_release_id === package_release_id &&
29
+ pf.file_path === file_path,
30
+ )
31
+
32
+ if (!packageFile) {
33
+ throw new NotFoundError("Package file not found")
34
+ }
35
+
36
+ return packageFile.package_file_id
37
+ }
38
+
39
+ if ("package_id" in descriptor) {
40
+ const { package_id, version, file_path } = descriptor
41
+
42
+ // Verify package exists
43
+ const pkg = ctx.db.packages.find(
44
+ (p: ZT.Package) => p.package_id === package_id,
45
+ )
46
+ if (!pkg) {
47
+ throw new NotFoundError("Package not found")
48
+ }
49
+
50
+ // Find the package release
51
+ let packageRelease
52
+ if (version) {
53
+ packageRelease = ctx.db.packageReleases.find(
54
+ (pr: ZT.PackageRelease) =>
55
+ pr.package_id === package_id && pr.version === version,
56
+ )
57
+ } else {
58
+ packageRelease = ctx.db.packageReleases.find(
59
+ (pr: ZT.PackageRelease) => pr.package_id === package_id && pr.is_latest,
60
+ )
61
+ }
62
+
63
+ if (!packageRelease) {
64
+ throw new NotFoundError("Package release not found")
65
+ }
66
+
67
+ // Find the file
68
+ const packageFile = ctx.db.packageFiles.find(
69
+ (pf: ZT.PackageFile) =>
70
+ pf.package_release_id === packageRelease.package_release_id &&
71
+ pf.file_path === file_path,
72
+ )
73
+
74
+ if (!packageFile) {
75
+ throw new NotFoundError("Package file not found")
76
+ }
77
+
78
+ return packageFile.package_file_id
79
+ }
80
+
81
+ if ("package_name" in descriptor) {
82
+ const { package_name, version, file_path } = descriptor
83
+
84
+ // Find the package first
85
+ const pkg = ctx.db.packages.find((p: ZT.Package) => p.name === package_name)
86
+ if (!pkg) {
87
+ throw new NotFoundError(`Package not found: ${package_name}`)
88
+ }
89
+
90
+ // Find the package release
91
+ let packageRelease
92
+ if (version) {
93
+ packageRelease = ctx.db.packageReleases.find(
94
+ (pr: ZT.PackageRelease) =>
95
+ pr.package_id === pkg.package_id && pr.version === version,
96
+ )
97
+ } else {
98
+ packageRelease = ctx.db.packageReleases.find(
99
+ (pr: ZT.PackageRelease) =>
100
+ pr.package_id === pkg.package_id && pr.is_latest,
101
+ )
102
+ }
103
+
104
+ if (!packageRelease) {
105
+ throw new NotFoundError("Package release not found")
106
+ }
107
+
108
+ // Find the file
109
+ const packageFile = ctx.db.packageFiles.find(
110
+ (pf: ZT.PackageFile) =>
111
+ pf.package_release_id === packageRelease.package_release_id &&
112
+ pf.file_path === file_path,
113
+ )
114
+
115
+ if (!packageFile) {
116
+ throw new NotFoundError("Package file not found")
117
+ }
118
+
119
+ return packageFile.package_file_id
120
+ }
121
+
122
+ if ("package_name_with_version" in descriptor) {
123
+ const { package_name_with_version, file_path } = descriptor
124
+ const packageName = package_name_with_version.split("@")[1]
125
+ const version = package_name_with_version.split("@")[2]
126
+
127
+ // Find the package
128
+ const pkg = ctx.db.packages.find((p: ZT.Package) => p.name === packageName)
129
+ if (!pkg) {
130
+ throw new NotFoundError(`Package not found: ${packageName}`)
131
+ }
132
+
133
+ // Find the package release
134
+ let packageRelease
135
+ if (!version || version === "latest") {
136
+ packageRelease = ctx.db.packageReleases.find(
137
+ (pr: ZT.PackageRelease) =>
138
+ pr.package_id === pkg.package_id && pr.is_latest,
139
+ )
140
+ } else {
141
+ packageRelease = ctx.db.packageReleases.find(
142
+ (pr: ZT.PackageRelease) =>
143
+ pr.package_id === pkg.package_id && pr.version === version,
144
+ )
145
+ }
146
+
147
+ if (!packageRelease) {
148
+ throw new NotFoundError(
149
+ `Package release not found for version: ${version || "latest"}`,
150
+ )
151
+ }
152
+
153
+ // Find the file
154
+ const packageFile = ctx.db.packageFiles.find(
155
+ (pf: ZT.PackageFile) =>
156
+ pf.package_release_id === packageRelease.package_release_id &&
157
+ pf.file_path === file_path,
158
+ )
159
+
160
+ if (!packageFile) {
161
+ throw new NotFoundError(`Package file not found: ${file_path}`)
162
+ }
163
+
164
+ return packageFile.package_file_id
165
+ }
166
+
167
+ throw new NotFoundError("Invalid package file descriptor")
168
+ }
@@ -0,0 +1,122 @@
1
+ import { Package, PackageRelease } from "fake-snippets-api/lib/db/schema"
2
+
3
+ export const findPackageReleaseId = async (
4
+ params:
5
+ | string
6
+ | {
7
+ package_release_id: string
8
+ }
9
+ | {
10
+ package_name: string
11
+ use_latest_version: true
12
+ }
13
+ | {
14
+ package_name_with_version: string
15
+ }
16
+ | {
17
+ package_release_id?: string | undefined
18
+ package_name_with_version?: string | undefined
19
+ },
20
+ ctx: { db: any },
21
+ ): Promise<string | null> => {
22
+ if (typeof params === "string") {
23
+ return findPackageReleaseIdFromPackageNameWithVersion(params, ctx.db)
24
+ }
25
+
26
+ if (
27
+ "package_name_with_version" in params &&
28
+ params.package_name_with_version
29
+ ) {
30
+ const { package_name_with_version } = params
31
+
32
+ if (package_name_with_version.endsWith("@latest")) {
33
+ const [packageName] = package_name_with_version.split("@")
34
+ return findPackageReleaseId(
35
+ {
36
+ package_name: packageName!,
37
+ use_latest_version: true,
38
+ },
39
+ ctx,
40
+ )
41
+ }
42
+ return findPackageReleaseIdFromPackageNameWithVersion(
43
+ package_name_with_version!,
44
+ ctx.db,
45
+ )
46
+ }
47
+
48
+ if ("package_release_id" in params && params.package_release_id) {
49
+ const packageRelease = ctx.db.packageReleases.find(
50
+ (pr: PackageRelease) =>
51
+ pr.package_release_id === params.package_release_id,
52
+ )
53
+ if (!packageRelease) {
54
+ return null
55
+ }
56
+ return params.package_release_id
57
+ }
58
+
59
+ if ("package_name" in params) {
60
+ const { package_name, use_latest_version } = params
61
+
62
+ if (!use_latest_version) {
63
+ throw new Error("use_latest_version must be true")
64
+ }
65
+
66
+ const pkg = ctx.db.packages.find(
67
+ (p: Package) => p.name === package_name.replace(/^@/, ""),
68
+ )
69
+ if (!pkg) {
70
+ return null
71
+ }
72
+
73
+ const packageRelease = ctx.db.packageReleases.find(
74
+ (pr: PackageRelease) => pr.package_id === pkg.package_id && pr.is_latest,
75
+ )
76
+
77
+ if (!packageRelease) {
78
+ return null
79
+ }
80
+
81
+ return packageRelease.package_release_id
82
+ }
83
+
84
+ return null
85
+ }
86
+
87
+ export const findPackageReleaseIdFromPackageNameWithVersion = (
88
+ packageNameWithVersion: string,
89
+ db: any,
90
+ ): string | null => {
91
+ if (!packageNameWithVersion) return null
92
+
93
+ const [packageName, version] = packageNameWithVersion
94
+ .replace(/^@/, "")
95
+ .split("@")
96
+
97
+ const pkg = db.packages.find((p: Package) => p.name === packageName)
98
+ if (!pkg) {
99
+ return null
100
+ }
101
+
102
+ let packageRelease
103
+
104
+ if (!version || version === "latest") {
105
+ packageRelease = db.packageReleases.find(
106
+ (pr: PackageRelease) => pr.package_id === pkg.package_id && pr.is_latest,
107
+ )
108
+ } else {
109
+ packageRelease = db.packageReleases.find(
110
+ (pr: PackageRelease) =>
111
+ pr.package_id === pkg.package_id && pr.version === version,
112
+ )
113
+ }
114
+
115
+ if (!packageRelease) {
116
+ return null
117
+ }
118
+
119
+ console.log("packageRelease", packageRelease)
120
+
121
+ return packageRelease.package_release_id
122
+ }
@@ -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
  })