@tscircuit/fake-snippets 0.0.35 → 0.0.37
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/.github/workflows/bun-test.yml +0 -3
- package/bun-tests/fake-snippets-api/fixtures/get-test-server.ts +1 -0
- package/bun-tests/fake-snippets-api/routes/package_files/create_or_update.test.ts +575 -0
- package/bun-tests/fake-snippets-api/routes/package_files/delete.test.ts +233 -0
- package/bun-tests/fake-snippets-api/routes/packages/fork.test.ts +133 -0
- package/dist/bundle.js +615 -236
- package/dist/index.d.ts +21 -2
- package/dist/index.js +29 -1
- package/fake-snippets-api/lib/db/db-client.ts +28 -0
- package/fake-snippets-api/lib/db/schema.ts +3 -0
- package/fake-snippets-api/routes/api/package_files/create_or_update.ts +179 -0
- package/fake-snippets-api/routes/api/package_files/delete.ts +106 -0
- package/fake-snippets-api/routes/api/packages/fork.ts +162 -0
- package/package.json +2 -3
- package/src/components/EditorNav.tsx +4 -4
- package/src/components/Footer.tsx +7 -1
- package/src/components/ViewPackagePage/components/package-header.tsx +0 -4
- package/src/components/dialogs/confirm-delete-package-dialog.tsx +48 -0
- package/src/hooks/use-delete-package.ts +40 -0
- package/src/hooks/use-fork-package-mutation.ts +14 -61
- package/src/pages/user-profile.tsx +15 -14
- package/src/components/dialogs/confirm-delete-snippet-dialog.tsx +0 -80
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { getTestServer } from "bun-tests/fake-snippets-api/fixtures/get-test-server"
|
|
2
|
+
import { expect, test } from "bun:test"
|
|
3
|
+
|
|
4
|
+
test("delete package file using package_release_id", async () => {
|
|
5
|
+
const { axios } = await getTestServer()
|
|
6
|
+
|
|
7
|
+
const packageResponse = await axios.post("/api/packages/create", {
|
|
8
|
+
name: "@test/package-files-delete",
|
|
9
|
+
description: "A test package for deleting files",
|
|
10
|
+
})
|
|
11
|
+
expect(packageResponse.status).toBe(200)
|
|
12
|
+
const createdPackage = packageResponse.data.package
|
|
13
|
+
|
|
14
|
+
const releaseResponse = await axios.post("/api/package_releases/create", {
|
|
15
|
+
package_id: createdPackage.package_id,
|
|
16
|
+
version: "1.0.0",
|
|
17
|
+
is_latest: true,
|
|
18
|
+
})
|
|
19
|
+
expect(releaseResponse.status).toBe(200)
|
|
20
|
+
const createdRelease = releaseResponse.data.package_release
|
|
21
|
+
|
|
22
|
+
const filePath = "/index.js"
|
|
23
|
+
const createResponse = await axios.post("/api/package_files/create", {
|
|
24
|
+
package_release_id: createdRelease.package_release_id,
|
|
25
|
+
file_path: filePath,
|
|
26
|
+
content_text: "console.log('Hello, world!');",
|
|
27
|
+
})
|
|
28
|
+
expect(createResponse.status).toBe(200)
|
|
29
|
+
const createdFile = createResponse.data.package_file
|
|
30
|
+
|
|
31
|
+
const deleteResponse = await axios.post("/api/package_files/delete", {
|
|
32
|
+
package_release_id: createdRelease.package_release_id,
|
|
33
|
+
file_path: filePath,
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
expect(deleteResponse.status).toBe(200)
|
|
37
|
+
expect(deleteResponse.data.ok).toBe(true)
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
await axios.post("/api/package_files/get", {
|
|
41
|
+
package_file_id: createdFile.package_file_id,
|
|
42
|
+
})
|
|
43
|
+
throw new Error("Expected request to fail")
|
|
44
|
+
} catch (error: any) {
|
|
45
|
+
expect(error.status).toBe(404)
|
|
46
|
+
expect(error.data.message).toBe("Package file not found")
|
|
47
|
+
}
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
test("delete package file using package_name_with_version", async () => {
|
|
51
|
+
const { axios } = await getTestServer()
|
|
52
|
+
|
|
53
|
+
const packageName = "@test/package-files-delete-by-name"
|
|
54
|
+
const version = "2.0.0"
|
|
55
|
+
const packageResponse = await axios.post("/api/packages/create", {
|
|
56
|
+
name: packageName,
|
|
57
|
+
description: "A test package for deleting files by name",
|
|
58
|
+
})
|
|
59
|
+
expect(packageResponse.status).toBe(200)
|
|
60
|
+
const createdPackage = packageResponse.data.package
|
|
61
|
+
|
|
62
|
+
const releaseResponse = await axios.post("/api/package_releases/create", {
|
|
63
|
+
package_id: createdPackage.package_id,
|
|
64
|
+
version,
|
|
65
|
+
is_latest: true,
|
|
66
|
+
})
|
|
67
|
+
expect(releaseResponse.status).toBe(200)
|
|
68
|
+
|
|
69
|
+
const filePath = "/README.md"
|
|
70
|
+
const createResponse = await axios.post("/api/package_files/create", {
|
|
71
|
+
package_name_with_version: `${packageName}@${version}`,
|
|
72
|
+
file_path: filePath,
|
|
73
|
+
content_text: "# Test Package\nThis is a test package.",
|
|
74
|
+
})
|
|
75
|
+
expect(createResponse.status).toBe(200)
|
|
76
|
+
const createdFile = createResponse.data.package_file
|
|
77
|
+
|
|
78
|
+
const deleteResponse = await axios.post("/api/package_files/delete", {
|
|
79
|
+
package_name_with_version: `${packageName}@${version}`,
|
|
80
|
+
file_path: filePath,
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
expect(deleteResponse.status).toBe(200)
|
|
84
|
+
expect(deleteResponse.data.ok).toBe(true)
|
|
85
|
+
|
|
86
|
+
try {
|
|
87
|
+
await axios.post("/api/package_files/get", {
|
|
88
|
+
package_file_id: createdFile.package_file_id,
|
|
89
|
+
})
|
|
90
|
+
throw new Error("Expected request to fail")
|
|
91
|
+
} catch (error: any) {
|
|
92
|
+
expect(error.status).toBe(404)
|
|
93
|
+
expect(error.data.message).toBe("Package file not found")
|
|
94
|
+
}
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
test("delete package file - 404 for non-existent package name", async () => {
|
|
98
|
+
const { axios } = await getTestServer()
|
|
99
|
+
|
|
100
|
+
try {
|
|
101
|
+
await axios.post("/api/package_files/delete", {
|
|
102
|
+
package_name_with_version: "non-existent-id",
|
|
103
|
+
file_path: "/test.js",
|
|
104
|
+
})
|
|
105
|
+
} catch (error: any) {
|
|
106
|
+
expect(error.status).toBe(404)
|
|
107
|
+
expect(error.data.error.error_code).toBe("package_release_not_found")
|
|
108
|
+
expect(error.data.error.message).toBe("Package release not found")
|
|
109
|
+
}
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
test("delete package file - 404 for non-existent package", async () => {
|
|
113
|
+
const { axios } = await getTestServer()
|
|
114
|
+
|
|
115
|
+
try {
|
|
116
|
+
await axios.post("/api/package_files/delete", {
|
|
117
|
+
package_name_with_version: "non-existent-package@1.0.0",
|
|
118
|
+
file_path: "/test.js",
|
|
119
|
+
})
|
|
120
|
+
throw new Error("Expected request to fail")
|
|
121
|
+
} catch (error: any) {
|
|
122
|
+
expect(error.status).toBe(404)
|
|
123
|
+
expect(error.data.error.error_code).toBe("package_release_not_found")
|
|
124
|
+
expect(error.data.error.message).toBe("Package release not found")
|
|
125
|
+
}
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
test("delete package file - 404 for non-existent file", async () => {
|
|
129
|
+
const { axios } = await getTestServer()
|
|
130
|
+
|
|
131
|
+
const packageResponse = await axios.post("/api/packages/create", {
|
|
132
|
+
name: "@test/package-files-delete-error",
|
|
133
|
+
description: "A test package for delete error cases",
|
|
134
|
+
})
|
|
135
|
+
expect(packageResponse.status).toBe(200)
|
|
136
|
+
const createdPackage = packageResponse.data.package
|
|
137
|
+
|
|
138
|
+
const releaseResponse = await axios.post("/api/package_releases/create", {
|
|
139
|
+
package_id: createdPackage.package_id,
|
|
140
|
+
version: "1.0.0",
|
|
141
|
+
})
|
|
142
|
+
expect(releaseResponse.status).toBe(200)
|
|
143
|
+
const createdRelease = releaseResponse.data.package_release
|
|
144
|
+
|
|
145
|
+
try {
|
|
146
|
+
await axios.post("/api/package_files/delete", {
|
|
147
|
+
package_release_id: createdRelease.package_release_id,
|
|
148
|
+
file_path: "/non-existent-file.js",
|
|
149
|
+
})
|
|
150
|
+
throw new Error("Expected request to fail")
|
|
151
|
+
} catch (error: any) {
|
|
152
|
+
expect(error.status).toBe(404)
|
|
153
|
+
expect(error.data.error.error_code).toBe("file_not_found")
|
|
154
|
+
expect(error.data.error.message).toBe("Package file not found")
|
|
155
|
+
}
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
test("delete package file - 403 for unauthorized user", async () => {
|
|
159
|
+
const { axios, db } = await getTestServer()
|
|
160
|
+
|
|
161
|
+
const pkg = {
|
|
162
|
+
name: "@test/package-files-delete-unauthorized",
|
|
163
|
+
owner_org_id: "different-org",
|
|
164
|
+
created_at: "2023-01-01T00:00:00Z",
|
|
165
|
+
updated_at: "2023-01-01T00:00:00Z",
|
|
166
|
+
description: "A test package for unauthorized delete",
|
|
167
|
+
}
|
|
168
|
+
const addedPackage: any = db.addPackage(pkg as any)
|
|
169
|
+
|
|
170
|
+
const releaseResponse = await axios.post("/api/package_releases/create", {
|
|
171
|
+
package_id: addedPackage.package_id,
|
|
172
|
+
version: "1.0.0",
|
|
173
|
+
})
|
|
174
|
+
expect(releaseResponse.status).toBe(200)
|
|
175
|
+
const createdRelease = releaseResponse.data.package_release
|
|
176
|
+
|
|
177
|
+
const filePath = "/test.js"
|
|
178
|
+
const createResponse = await axios.post("/api/package_files/create", {
|
|
179
|
+
package_release_id: createdRelease.package_release_id,
|
|
180
|
+
file_path: filePath,
|
|
181
|
+
content_text: "console.log('test');",
|
|
182
|
+
})
|
|
183
|
+
expect(createResponse.status).toBe(200)
|
|
184
|
+
|
|
185
|
+
try {
|
|
186
|
+
await axios.post("/api/package_files/delete", {
|
|
187
|
+
package_release_id: createdRelease.package_release_id,
|
|
188
|
+
file_path: filePath,
|
|
189
|
+
})
|
|
190
|
+
throw new Error("Expected request to fail")
|
|
191
|
+
} catch (error: any) {
|
|
192
|
+
expect(error.status).toBe(403)
|
|
193
|
+
expect(error.data.error.error_code).toBe("forbidden")
|
|
194
|
+
expect(error.data.error.message).toBe(
|
|
195
|
+
"You don't have permission to delete files in this package",
|
|
196
|
+
)
|
|
197
|
+
}
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
test("delete package file - 400 when neither package_release_id nor package_name_with_version is provided", async () => {
|
|
201
|
+
const { axios } = await getTestServer()
|
|
202
|
+
|
|
203
|
+
try {
|
|
204
|
+
await axios.post("/api/package_files/delete", {
|
|
205
|
+
file_path: "/test.js",
|
|
206
|
+
})
|
|
207
|
+
throw new Error("Expected request to fail")
|
|
208
|
+
} catch (error: any) {
|
|
209
|
+
console.log(59, error)
|
|
210
|
+
expect(error.status).toBe(400)
|
|
211
|
+
expect(error.data.message).toInclude(
|
|
212
|
+
"Must specify either package_release_id or package_name_with_version",
|
|
213
|
+
)
|
|
214
|
+
}
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
test("delete package file - 400 when both package_release_id and package_name_with_version are provided", async () => {
|
|
218
|
+
const { axios } = await getTestServer()
|
|
219
|
+
|
|
220
|
+
try {
|
|
221
|
+
await axios.post("/api/package_files/delete", {
|
|
222
|
+
package_release_id: "some-id",
|
|
223
|
+
package_name_with_version: "@test/package@1.0.0",
|
|
224
|
+
file_path: "/test.js",
|
|
225
|
+
})
|
|
226
|
+
throw new Error("Expected request to fail")
|
|
227
|
+
} catch (error: any) {
|
|
228
|
+
expect(error.status).toBe(400)
|
|
229
|
+
expect(error.data.message).toInclude(
|
|
230
|
+
"Cannot specify both package_release_id and package_name_with_version",
|
|
231
|
+
)
|
|
232
|
+
}
|
|
233
|
+
})
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { getTestServer } from "bun-tests/fake-snippets-api/fixtures/get-test-server"
|
|
2
|
+
import { test, expect } from "bun:test"
|
|
3
|
+
|
|
4
|
+
test("POST /packages/fork - successful fork using package_id", async () => {
|
|
5
|
+
const { axios, jane_axios } = await getTestServer()
|
|
6
|
+
|
|
7
|
+
// user creates a package with files
|
|
8
|
+
const sourcePackage = await axios
|
|
9
|
+
.post("/api/packages/create", {
|
|
10
|
+
name: "testuser/test-package-for-fork",
|
|
11
|
+
description: "A package to be forked",
|
|
12
|
+
})
|
|
13
|
+
.then((r: any) => r.data.package)
|
|
14
|
+
|
|
15
|
+
// user creates a release
|
|
16
|
+
const sourceRelease = await axios
|
|
17
|
+
.post("/api/package_releases/create", {
|
|
18
|
+
package_id: sourcePackage.package_id,
|
|
19
|
+
version: "1.0.0",
|
|
20
|
+
})
|
|
21
|
+
.then((r: any) => r.data.package_release)
|
|
22
|
+
|
|
23
|
+
// user creates a file
|
|
24
|
+
await axios.post("/api/package_files/create", {
|
|
25
|
+
package_release_id: sourceRelease.package_release_id,
|
|
26
|
+
file_path: "index.tsx",
|
|
27
|
+
content_text: "console.log('Hello from original package');",
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
// Jane forks the package
|
|
31
|
+
const forkedPackageResponse = await jane_axios.post("/api/packages/fork", {
|
|
32
|
+
package_id: sourcePackage.package_id,
|
|
33
|
+
is_private: false,
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
const forkedPackage = forkedPackageResponse.data.package
|
|
37
|
+
|
|
38
|
+
// Verify fork was created successfully
|
|
39
|
+
expect(forkedPackage.name).toBe(`jane/${sourcePackage.unscoped_name}`)
|
|
40
|
+
expect(forkedPackage.description).toBe(sourcePackage.description)
|
|
41
|
+
expect(forkedPackage.is_private).toBe(false)
|
|
42
|
+
|
|
43
|
+
// List files from the forked package
|
|
44
|
+
const packageFilesResponse = await jane_axios.post(
|
|
45
|
+
"/api/package_files/list",
|
|
46
|
+
{
|
|
47
|
+
package_name: forkedPackage.name,
|
|
48
|
+
use_latest_version: true,
|
|
49
|
+
},
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
const package_files = packageFilesResponse.data.package_files
|
|
53
|
+
|
|
54
|
+
expect(package_files.length).toBe(1)
|
|
55
|
+
expect(package_files[0].file_path).toBe("index.tsx")
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
test("POST /packages/fork - successful fork using package_name", async () => {
|
|
59
|
+
const { axios, jane_axios } = await getTestServer()
|
|
60
|
+
|
|
61
|
+
// Jane creates a package with files
|
|
62
|
+
const sourcePackage = await jane_axios
|
|
63
|
+
.post("/api/packages/create", {
|
|
64
|
+
name: "jane/test-package-for-name-fork",
|
|
65
|
+
description: "A package to be forked by name",
|
|
66
|
+
})
|
|
67
|
+
.then((r: any) => r.data.package)
|
|
68
|
+
|
|
69
|
+
// Create a release
|
|
70
|
+
const sourceRelease = await jane_axios
|
|
71
|
+
.post("/api/package_releases/create", {
|
|
72
|
+
package_id: sourcePackage.package_id,
|
|
73
|
+
version: "1.0.0",
|
|
74
|
+
})
|
|
75
|
+
.then((r: any) => r.data.package_release)
|
|
76
|
+
|
|
77
|
+
// Create a file
|
|
78
|
+
await jane_axios.post("/api/package_files/create", {
|
|
79
|
+
package_release_id: sourceRelease.package_release_id,
|
|
80
|
+
file_path: "index.tsx",
|
|
81
|
+
content_text: "console.log('Hello from name package');",
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
// user forks Jane's package using package_name
|
|
85
|
+
const forkedPackage = await axios
|
|
86
|
+
.post("/api/packages/fork", {
|
|
87
|
+
package_name: "jane/test-package-for-name-fork",
|
|
88
|
+
is_private: true,
|
|
89
|
+
})
|
|
90
|
+
.then((r: any) => r.data.package)
|
|
91
|
+
|
|
92
|
+
// Verify fork was created successfully with privacy settings
|
|
93
|
+
expect(forkedPackage.name).toBe(`testuser/${sourcePackage.unscoped_name}`)
|
|
94
|
+
expect(forkedPackage.is_private).toBe(true)
|
|
95
|
+
expect(forkedPackage.is_unlisted).toBe(true) // Should be unlisted since it's private
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
test("POST /packages/fork - error when package not found", async () => {
|
|
99
|
+
const { axios } = await getTestServer()
|
|
100
|
+
|
|
101
|
+
try {
|
|
102
|
+
await axios.post("/api/packages/fork", {
|
|
103
|
+
package_id: "00000000-0000-0000-0000-000000000000", // Non-existent ID
|
|
104
|
+
})
|
|
105
|
+
// If it doesn't throw, fail the test
|
|
106
|
+
expect(true).toBe(false)
|
|
107
|
+
} catch (error: any) {
|
|
108
|
+
expect(error.status).toBe(404)
|
|
109
|
+
expect(error.data.error.error_code).toBe("package_not_found")
|
|
110
|
+
}
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
test("POST /packages/fork - error when trying to fork own package", async () => {
|
|
114
|
+
const { jane_axios } = await getTestServer()
|
|
115
|
+
|
|
116
|
+
const sourcePackage = await jane_axios
|
|
117
|
+
.post("/api/packages/create", {
|
|
118
|
+
name: "jane/test-package-for-fork",
|
|
119
|
+
description: "A package to be forked",
|
|
120
|
+
})
|
|
121
|
+
.then((r: any) => r.data.package)
|
|
122
|
+
|
|
123
|
+
try {
|
|
124
|
+
await jane_axios.post("/api/packages/fork", {
|
|
125
|
+
package_id: sourcePackage.package_id,
|
|
126
|
+
})
|
|
127
|
+
// If it doesn't throw, fail the test
|
|
128
|
+
expect(true).toBe(false)
|
|
129
|
+
} catch (error: any) {
|
|
130
|
+
expect(error.status).toBe(400)
|
|
131
|
+
expect(error.data.error.error_code).toBe("cannot_fork_own_package")
|
|
132
|
+
}
|
|
133
|
+
})
|