@tscircuit/fake-snippets 0.0.3 → 0.0.5
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/bundle-size-analysis.yml +2 -2
- package/bun-tests/fake-snippets-api/routes/package_releases/create.test.ts +131 -0
- package/bun-tests/fake-snippets-api/routes/package_releases/get.test.ts +89 -0
- package/bun-tests/fake-snippets-api/routes/package_releases/list.test.ts +157 -0
- package/bun-tests/fake-snippets-api/routes/package_releases/update.test.ts +189 -0
- package/bun-tests/fake-snippets-api/routes/packages/create.test.ts +26 -0
- package/bun-tests/fake-snippets-api/routes/packages/delete.test.ts +100 -0
- package/bun-tests/fake-snippets-api/routes/packages/get.test.ts +59 -0
- package/bun-tests/fake-snippets-api/routes/packages/list.test.ts +167 -0
- package/bun.lock +3514 -0
- package/dist/bundle.js +741 -108
- package/fake-snippets-api/lib/db/db-client.ts +79 -2
- package/fake-snippets-api/lib/db/schema.ts +55 -0
- package/fake-snippets-api/lib/public-mapping/public-map-package-release.ts +10 -0
- package/fake-snippets-api/lib/public-mapping/public-map-package.ts +31 -0
- package/fake-snippets-api/lib/with-winter-spec.ts +1 -0
- package/fake-snippets-api/routes/api/package_files/download.ts +170 -0
- package/fake-snippets-api/routes/api/package_files/get.ts +52 -0
- package/fake-snippets-api/routes/api/package_files/list.ts +60 -0
- package/fake-snippets-api/routes/api/package_releases/create.ts +83 -0
- package/fake-snippets-api/routes/api/package_releases/get.ts +34 -0
- package/fake-snippets-api/routes/api/package_releases/list.ts +77 -0
- package/fake-snippets-api/routes/api/package_releases/update.ts +96 -0
- package/fake-snippets-api/routes/api/packages/create.ts +58 -0
- package/fake-snippets-api/routes/api/packages/delete.ts +43 -0
- package/fake-snippets-api/routes/api/packages/get.ts +36 -0
- package/fake-snippets-api/routes/api/packages/list.ts +56 -0
- package/fake-snippets-api/routes/api/snippets/create.ts +5 -3
- package/package.json +12 -9
- package/playwright-tests/circuit-json-import.spec.ts +133 -0
- package/playwright-tests/cmd-click.spec.ts +1 -1
- package/playwright-tests/editor-page.spec.ts +1 -1
- package/playwright-tests/exampleCircuitJson.ts +498 -0
- package/playwright-tests/preview-page.spec.ts +2 -9
- package/playwright-tests/snapshots/cmd-click.spec.ts-underlined-imports.png +0 -0
- package/playwright-tests/snapshots/editor-page.spec.ts-editor-with-snippet.png +0 -0
- package/playwright-tests/snapshots/preview-page.spec.ts-preview-snippet-pcb.png +0 -0
- package/src/components/CircuitJsonImportDialog.tsx +186 -0
- package/src/components/CodeAndPreview.tsx +60 -2
- package/src/components/EditorNav.tsx +23 -2
- package/src/components/FootprintDialog.tsx +3 -6
- package/src/components/Header2.tsx +7 -0
- package/src/components/PrefetchPageLink.tsx +4 -1
- package/src/components/SuspenseRunFrame.tsx +16 -0
- package/src/components/dialogs/import-snippet-dialog.tsx +12 -8
- package/src/hooks/use-debounce.ts +17 -0
- package/src/hooks/use-global-store.ts +5 -0
- package/src/hooks/use-run-tsx/index.tsx +1 -0
- package/src/pages/landing.tsx +2 -2
- package/src/pages/preview.tsx +2 -28
- package/src/pages/quickstart.tsx +24 -0
- package/vite.config.ts +1 -1
- package/bun.lockb +0 -0
- package/playwright-tests/snapshots/preview-page.spec.ts-preview-snippet-schematic.png +0 -0
|
@@ -14,6 +14,10 @@ import {
|
|
|
14
14
|
Order,
|
|
15
15
|
OrderFile,
|
|
16
16
|
AccountSnippet,
|
|
17
|
+
packageReleaseSchema,
|
|
18
|
+
packageSchema,
|
|
19
|
+
Package,
|
|
20
|
+
PackageRelease,
|
|
17
21
|
} from "./schema.ts"
|
|
18
22
|
import { combine } from "zustand/middleware"
|
|
19
23
|
import { seed as seedFn } from "./seed"
|
|
@@ -85,17 +89,31 @@ const initializer = combine(databaseSchema.parse({}), (set, get) => ({
|
|
|
85
89
|
return newAccount
|
|
86
90
|
},
|
|
87
91
|
addSnippet: (
|
|
88
|
-
snippet: Omit<
|
|
92
|
+
snippet: Omit<
|
|
93
|
+
z.input<typeof snippetSchema>,
|
|
94
|
+
"snippet_id" | "package_release_id"
|
|
95
|
+
>,
|
|
89
96
|
): Snippet => {
|
|
90
97
|
const newSnippetId = `snippet_${get().idCounter + 1}`
|
|
98
|
+
const newPackageRelease = packageReleaseSchema.parse({
|
|
99
|
+
package_release_id: `package_release_${get().idCounter + 1}`,
|
|
100
|
+
package_id: newSnippetId,
|
|
101
|
+
version: "0.0.1",
|
|
102
|
+
is_locked: false,
|
|
103
|
+
is_latest: true,
|
|
104
|
+
created_at: new Date().toISOString(),
|
|
105
|
+
updated_at: new Date().toISOString(),
|
|
106
|
+
})
|
|
91
107
|
const newSnippet = snippetSchema.parse({
|
|
92
108
|
...snippet,
|
|
93
109
|
snippet_id: newSnippetId,
|
|
110
|
+
package_release_id: newPackageRelease.package_release_id,
|
|
94
111
|
})
|
|
95
112
|
set((state) => {
|
|
96
113
|
return {
|
|
97
114
|
snippets: [...state.snippets, newSnippet],
|
|
98
|
-
|
|
115
|
+
packageReleases: [...state.packageReleases, newPackageRelease],
|
|
116
|
+
idCounter: state.idCounter + 2,
|
|
99
117
|
}
|
|
100
118
|
})
|
|
101
119
|
return { ...newSnippet, snippet_id: newSnippetId }
|
|
@@ -340,4 +358,63 @@ const initializer = combine(databaseSchema.parse({}), (set, get) => ({
|
|
|
340
358
|
as.has_starred,
|
|
341
359
|
)
|
|
342
360
|
},
|
|
361
|
+
addPackage: (
|
|
362
|
+
_package: Omit<z.input<typeof packageSchema>, "package_id">,
|
|
363
|
+
): Package => {
|
|
364
|
+
const newPackage = {
|
|
365
|
+
package_id: `package_${Date.now()}`,
|
|
366
|
+
..._package,
|
|
367
|
+
}
|
|
368
|
+
const packageRelease = packageReleaseSchema.parse({
|
|
369
|
+
package_release_id: `package_release_${Date.now()}`,
|
|
370
|
+
package_id: newPackage.package_id,
|
|
371
|
+
version: "0.0.1",
|
|
372
|
+
is_locked: false,
|
|
373
|
+
is_latest: true,
|
|
374
|
+
created_at: new Date().toISOString(),
|
|
375
|
+
updated_at: new Date().toISOString(),
|
|
376
|
+
})
|
|
377
|
+
newPackage.latest_package_release_id = packageRelease.package_release_id
|
|
378
|
+
set((state) => ({
|
|
379
|
+
packages: [...state.packages, newPackage],
|
|
380
|
+
}))
|
|
381
|
+
return newPackage
|
|
382
|
+
},
|
|
383
|
+
getPackageById: (package_id: string): Package | undefined => {
|
|
384
|
+
const state = get()
|
|
385
|
+
const pkg = state.packages.find((pkg) => pkg.package_id === package_id)
|
|
386
|
+
if (!pkg) return undefined
|
|
387
|
+
return {
|
|
388
|
+
...pkg,
|
|
389
|
+
}
|
|
390
|
+
},
|
|
391
|
+
getPackageReleaseById: (
|
|
392
|
+
package_release_id: string,
|
|
393
|
+
): PackageRelease | undefined => {
|
|
394
|
+
const state = get()
|
|
395
|
+
return state.packageReleases.find(
|
|
396
|
+
(pr) => pr.package_release_id === package_release_id,
|
|
397
|
+
)
|
|
398
|
+
},
|
|
399
|
+
addPackageRelease: (
|
|
400
|
+
packageRelease: Omit<PackageRelease, "package_release_id">,
|
|
401
|
+
): PackageRelease => {
|
|
402
|
+
const newPackageRelease = {
|
|
403
|
+
package_release_id: `package_release_${Date.now()}`,
|
|
404
|
+
...packageRelease,
|
|
405
|
+
}
|
|
406
|
+
set((state) => ({
|
|
407
|
+
packageReleases: [...state.packageReleases, newPackageRelease],
|
|
408
|
+
}))
|
|
409
|
+
return newPackageRelease
|
|
410
|
+
},
|
|
411
|
+
updatePackageRelease: (packageRelease: PackageRelease): void => {
|
|
412
|
+
set((state) => ({
|
|
413
|
+
packageReleases: state.packageReleases.map((pr) =>
|
|
414
|
+
pr.package_release_id === packageRelease.package_release_id
|
|
415
|
+
? packageRelease
|
|
416
|
+
: pr,
|
|
417
|
+
),
|
|
418
|
+
}))
|
|
419
|
+
},
|
|
343
420
|
}))
|
|
@@ -2,6 +2,7 @@ import { z } from "zod"
|
|
|
2
2
|
|
|
3
3
|
export const snippetSchema = z.object({
|
|
4
4
|
snippet_id: z.string(),
|
|
5
|
+
package_release_id: z.string(),
|
|
5
6
|
name: z.string(),
|
|
6
7
|
unscoped_name: z.string(),
|
|
7
8
|
owner_name: z.string(),
|
|
@@ -99,12 +100,66 @@ export const accountSnippetSchema = z.object({
|
|
|
99
100
|
})
|
|
100
101
|
export type AccountSnippet = z.infer<typeof accountSnippetSchema>
|
|
101
102
|
|
|
103
|
+
export const packageReleaseSchema = z.object({
|
|
104
|
+
package_release_id: z.string(),
|
|
105
|
+
package_id: z.string(),
|
|
106
|
+
version: z.string().nullable(),
|
|
107
|
+
is_locked: z.boolean(),
|
|
108
|
+
is_latest: z.boolean(),
|
|
109
|
+
created_at: z.string().datetime(),
|
|
110
|
+
commit_sha: z.string().nullable().optional(),
|
|
111
|
+
license: z.string().nullable().optional(),
|
|
112
|
+
})
|
|
113
|
+
export type PackageRelease = z.infer<typeof packageReleaseSchema>
|
|
114
|
+
|
|
115
|
+
export const packageFileSchema = z.object({
|
|
116
|
+
package_file_id: z.string(),
|
|
117
|
+
package_release_id: z.string(),
|
|
118
|
+
file_path: z.string(),
|
|
119
|
+
content_text: z.string().nullable().optional(),
|
|
120
|
+
created_at: z.string().datetime(),
|
|
121
|
+
})
|
|
122
|
+
export type PackageFile = z.infer<typeof packageFileSchema>
|
|
123
|
+
|
|
124
|
+
export const packageSchema = z.object({
|
|
125
|
+
package_id: z.string(),
|
|
126
|
+
creator_account_id: z.string(),
|
|
127
|
+
latest_package_release_id: z.string().nullable(),
|
|
128
|
+
latest_version: z.string().nullable(),
|
|
129
|
+
license: z.string().nullable(),
|
|
130
|
+
owner_org_id: z.string(),
|
|
131
|
+
owner_github_username: z.string().nullable(),
|
|
132
|
+
is_source_from_github: z.boolean(),
|
|
133
|
+
description: z.string().nullable(),
|
|
134
|
+
name: z.string(),
|
|
135
|
+
unscoped_name: z.string(),
|
|
136
|
+
star_count: z.number(),
|
|
137
|
+
created_at: z.string().datetime(),
|
|
138
|
+
updated_at: z.string().datetime(),
|
|
139
|
+
ai_description: z.string().nullable(),
|
|
140
|
+
})
|
|
141
|
+
export type Package = z.infer<typeof packageSchema>
|
|
142
|
+
|
|
143
|
+
export const errorSchema = z
|
|
144
|
+
.object({
|
|
145
|
+
error_code: z.string(),
|
|
146
|
+
message: z.string(),
|
|
147
|
+
})
|
|
148
|
+
.passthrough()
|
|
149
|
+
|
|
150
|
+
export const errorResponseSchema = z.object({
|
|
151
|
+
error: errorSchema,
|
|
152
|
+
})
|
|
153
|
+
|
|
102
154
|
export const databaseSchema = z.object({
|
|
103
155
|
idCounter: z.number().default(0),
|
|
104
156
|
snippets: z.array(snippetSchema).default([]),
|
|
157
|
+
packageReleases: z.array(packageReleaseSchema).default([]),
|
|
158
|
+
packageFiles: z.array(packageFileSchema).default([]),
|
|
105
159
|
sessions: z.array(sessionSchema).default([]),
|
|
106
160
|
loginPages: z.array(loginPageSchema).default([]),
|
|
107
161
|
accounts: z.array(accountSchema).default([]),
|
|
162
|
+
packages: z.array(packageSchema).default([]),
|
|
108
163
|
orders: z.array(orderSchema).default([]),
|
|
109
164
|
orderFiles: z.array(orderFileSchema).default([]),
|
|
110
165
|
accountSnippets: z.array(accountSnippetSchema).default([]),
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as ZT from "fake-snippets-api/lib/db/schema"
|
|
2
|
+
|
|
3
|
+
export const publicMapPackageRelease = (
|
|
4
|
+
internal_package_release: ZT.PackageRelease,
|
|
5
|
+
): ZT.PackageRelease => {
|
|
6
|
+
return {
|
|
7
|
+
...internal_package_release,
|
|
8
|
+
created_at: internal_package_release.created_at,
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { z } from "zod"
|
|
2
|
+
import * as ZT from "fake-snippets-api/lib/db/schema"
|
|
3
|
+
|
|
4
|
+
export const publicMapPackage = (internal_package: {
|
|
5
|
+
package_id: string
|
|
6
|
+
creator_account_id: string
|
|
7
|
+
owner_org_id: string
|
|
8
|
+
owner_github_username: string | null
|
|
9
|
+
is_source_from_github: boolean
|
|
10
|
+
description: string | null
|
|
11
|
+
latest_version?: string | null
|
|
12
|
+
latest_license?: string | null
|
|
13
|
+
latest_package_release_id?: string | null
|
|
14
|
+
star_count?: number | null
|
|
15
|
+
name: string
|
|
16
|
+
unscoped_name: string
|
|
17
|
+
updated_at: string
|
|
18
|
+
created_at: string
|
|
19
|
+
ai_description: string | null
|
|
20
|
+
}): ZT.Package => {
|
|
21
|
+
return {
|
|
22
|
+
...internal_package,
|
|
23
|
+
latest_package_release_id:
|
|
24
|
+
internal_package.latest_package_release_id ?? null,
|
|
25
|
+
latest_version: internal_package.latest_version ?? null,
|
|
26
|
+
license: internal_package.latest_license ?? null,
|
|
27
|
+
star_count: internal_package.star_count ?? 0,
|
|
28
|
+
created_at: internal_package.created_at,
|
|
29
|
+
updated_at: internal_package.updated_at,
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./middleware/with-winter-spec"
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { withRouteSpec } from "fake-snippets-api/lib/with-winter-spec"
|
|
2
|
+
import { z } from "zod"
|
|
3
|
+
|
|
4
|
+
export default withRouteSpec({
|
|
5
|
+
methods: ["GET"],
|
|
6
|
+
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",
|
|
24
|
+
})
|
|
25
|
+
}
|
|
26
|
+
const [packageName, version] = packageWithVersion.split("@")
|
|
27
|
+
const fileName = rest.join("/")
|
|
28
|
+
|
|
29
|
+
// Find the snippet
|
|
30
|
+
// const snippet =
|
|
31
|
+
|
|
32
|
+
// if (!snippet) {
|
|
33
|
+
// return ctx.error(404, {
|
|
34
|
+
// error_code: "snippet_not_found",
|
|
35
|
+
// message: "Snippet not found",
|
|
36
|
+
// })
|
|
37
|
+
// }
|
|
38
|
+
|
|
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
|
+
// }
|
|
53
|
+
|
|
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
|
+
// }
|
|
65
|
+
|
|
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()
|
|
79
|
+
|
|
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
|
+
// ]
|
|
110
|
+
|
|
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
|
+
// }
|
|
129
|
+
|
|
130
|
+
// return new Response(JSON.stringify(response, null, 2), {
|
|
131
|
+
// status: 200,
|
|
132
|
+
// headers: { "Content-Type": "application/json" },
|
|
133
|
+
// })
|
|
134
|
+
// }
|
|
135
|
+
|
|
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
|
+
// }
|
|
163
|
+
|
|
164
|
+
const content = "TODO"
|
|
165
|
+
|
|
166
|
+
return new Response(content, {
|
|
167
|
+
status: 200,
|
|
168
|
+
headers: { "Content-Type": "text/plain" },
|
|
169
|
+
})
|
|
170
|
+
})
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { withRouteSpec } from "fake-snippets-api/lib/with-winter-spec"
|
|
2
|
+
import { z } from "zod"
|
|
3
|
+
import * as ZT from "fake-snippets-api/lib/db/schema"
|
|
4
|
+
import { NotFoundError } from "winterspec/middleware"
|
|
5
|
+
|
|
6
|
+
const routeSpec = {
|
|
7
|
+
methods: ["POST"],
|
|
8
|
+
auth: "none",
|
|
9
|
+
jsonBody: z
|
|
10
|
+
.object({
|
|
11
|
+
package_file_id: z.string().uuid(),
|
|
12
|
+
})
|
|
13
|
+
.or(
|
|
14
|
+
z.object({
|
|
15
|
+
package_release_id: z.string().uuid(),
|
|
16
|
+
file_path: z.string(),
|
|
17
|
+
}),
|
|
18
|
+
)
|
|
19
|
+
.or(
|
|
20
|
+
z.object({
|
|
21
|
+
package_id: z.string().uuid(),
|
|
22
|
+
version: z.string().optional(),
|
|
23
|
+
file_path: z.string(),
|
|
24
|
+
}),
|
|
25
|
+
)
|
|
26
|
+
.or(
|
|
27
|
+
z.object({
|
|
28
|
+
package_name: z.string(),
|
|
29
|
+
version: z.string().optional(),
|
|
30
|
+
file_path: z.string(),
|
|
31
|
+
}),
|
|
32
|
+
)
|
|
33
|
+
.or(
|
|
34
|
+
z.object({
|
|
35
|
+
package_name_with_version: z.string(),
|
|
36
|
+
file_path: z.string(),
|
|
37
|
+
}),
|
|
38
|
+
),
|
|
39
|
+
jsonResponse: z
|
|
40
|
+
.object({
|
|
41
|
+
ok: z.boolean(),
|
|
42
|
+
package_file: ZT.packageFileSchema.optional(),
|
|
43
|
+
})
|
|
44
|
+
.or(ZT.errorResponseSchema),
|
|
45
|
+
} as const
|
|
46
|
+
|
|
47
|
+
export default withRouteSpec(routeSpec)(async (req, ctx) => {
|
|
48
|
+
return ctx.json({
|
|
49
|
+
ok: true,
|
|
50
|
+
package_file: undefined,
|
|
51
|
+
})
|
|
52
|
+
})
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { withRouteSpec } from "fake-snippets-api/lib/with-winter-spec"
|
|
2
|
+
import { z } from "zod"
|
|
3
|
+
import * as ZT from "fake-snippets-api/lib/db/schema"
|
|
4
|
+
|
|
5
|
+
const routeSpec = {
|
|
6
|
+
methods: ["POST"],
|
|
7
|
+
auth: "none",
|
|
8
|
+
jsonBody: z
|
|
9
|
+
.object({
|
|
10
|
+
package_release_id: z.string().uuid(),
|
|
11
|
+
})
|
|
12
|
+
.or(
|
|
13
|
+
z.object({
|
|
14
|
+
package_name: z.string(),
|
|
15
|
+
use_latest_version: z.literal(true),
|
|
16
|
+
}),
|
|
17
|
+
)
|
|
18
|
+
.or(
|
|
19
|
+
z.object({
|
|
20
|
+
package_name_with_version: z.string(),
|
|
21
|
+
}),
|
|
22
|
+
),
|
|
23
|
+
jsonResponse: z.object({
|
|
24
|
+
ok: z.boolean(),
|
|
25
|
+
package_files: z.array(ZT.packageFileSchema),
|
|
26
|
+
}),
|
|
27
|
+
} as const
|
|
28
|
+
|
|
29
|
+
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
|
+
// })
|
|
56
|
+
return ctx.json({
|
|
57
|
+
ok: true,
|
|
58
|
+
package_files: [],
|
|
59
|
+
})
|
|
60
|
+
})
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { packageReleaseSchema } from "fake-snippets-api/lib/db/schema"
|
|
2
|
+
import { withRouteSpec } from "fake-snippets-api/lib/middleware/with-winter-spec"
|
|
3
|
+
import { publicMapPackageRelease } from "fake-snippets-api/lib/public-mapping/public-map-package-release"
|
|
4
|
+
import { z } from "zod"
|
|
5
|
+
|
|
6
|
+
export default withRouteSpec({
|
|
7
|
+
methods: ["POST"],
|
|
8
|
+
auth: "none",
|
|
9
|
+
jsonBody: z.object({
|
|
10
|
+
package_id: z.string().optional(),
|
|
11
|
+
version: z.string().optional(),
|
|
12
|
+
is_latest: z.boolean().optional(),
|
|
13
|
+
commit_sha: z.string().optional(),
|
|
14
|
+
package_name_with_version: z.string().optional(),
|
|
15
|
+
}),
|
|
16
|
+
jsonResponse: z.object({
|
|
17
|
+
ok: z.boolean(),
|
|
18
|
+
package_release: packageReleaseSchema,
|
|
19
|
+
}),
|
|
20
|
+
})(async (req, ctx) => {
|
|
21
|
+
let {
|
|
22
|
+
package_id,
|
|
23
|
+
is_latest = true,
|
|
24
|
+
version,
|
|
25
|
+
commit_sha,
|
|
26
|
+
package_name_with_version,
|
|
27
|
+
} = req.jsonBody
|
|
28
|
+
|
|
29
|
+
if (package_name_with_version && !version && !package_id) {
|
|
30
|
+
const [packageName, parsedVersion] = package_name_with_version.split("@")
|
|
31
|
+
const pkg = ctx.db.packages.find((p) => p.name === packageName)
|
|
32
|
+
|
|
33
|
+
if (!pkg) {
|
|
34
|
+
return ctx.error(404, {
|
|
35
|
+
error_code: "package_not_found",
|
|
36
|
+
message: `Package not found: ${packageName}`,
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
package_id = pkg.package_id
|
|
41
|
+
version = parsedVersion
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (!package_id || !version) {
|
|
45
|
+
return ctx.error(400, {
|
|
46
|
+
error_code: "missing_options",
|
|
47
|
+
message: "package_id and version are required",
|
|
48
|
+
})
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Check if version already exists
|
|
52
|
+
const existingRelease = ctx.db.packageReleases.find(
|
|
53
|
+
(pr) => pr.package_id === package_id && pr.version === version,
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
if (existingRelease) {
|
|
57
|
+
return ctx.error(400, {
|
|
58
|
+
error_code: "version_already_exists",
|
|
59
|
+
message: `Version ${version} already exists for this package`,
|
|
60
|
+
})
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Update previous latest if needed
|
|
64
|
+
if (is_latest) {
|
|
65
|
+
ctx.db.packageReleases
|
|
66
|
+
.filter((pr) => pr.package_id === package_id && pr.is_latest)
|
|
67
|
+
.forEach((pr) => (pr.is_latest = false))
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const newPackageRelease = ctx.db.addPackageRelease({
|
|
71
|
+
package_id,
|
|
72
|
+
is_latest,
|
|
73
|
+
version,
|
|
74
|
+
is_locked: false,
|
|
75
|
+
created_at: new Date().toISOString(),
|
|
76
|
+
commit_sha: commit_sha ?? null,
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
return ctx.json({
|
|
80
|
+
ok: true,
|
|
81
|
+
package_release: publicMapPackageRelease(newPackageRelease),
|
|
82
|
+
})
|
|
83
|
+
})
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import * as zt from "fake-snippets-api/lib/db/schema"
|
|
2
|
+
import { publicMapPackageRelease } from "fake-snippets-api/lib/public-mapping/public-map-package-release"
|
|
3
|
+
import { withRouteSpec } from "fake-snippets-api/lib/with-winter-spec"
|
|
4
|
+
import { z } from "zod"
|
|
5
|
+
|
|
6
|
+
export default withRouteSpec({
|
|
7
|
+
methods: ["POST"],
|
|
8
|
+
auth: "none",
|
|
9
|
+
jsonBody: z.object({
|
|
10
|
+
package_release_id: z.string().optional(),
|
|
11
|
+
package_name_with_version: z.string().optional(),
|
|
12
|
+
}),
|
|
13
|
+
jsonResponse: z.object({
|
|
14
|
+
ok: z.boolean(),
|
|
15
|
+
package_release: zt.packageReleaseSchema,
|
|
16
|
+
}),
|
|
17
|
+
})(async (req, ctx) => {
|
|
18
|
+
const { package_release_id } = req.jsonBody
|
|
19
|
+
|
|
20
|
+
const foundRelease =
|
|
21
|
+
package_release_id && ctx.db.getPackageReleaseById(package_release_id)
|
|
22
|
+
|
|
23
|
+
if (!foundRelease) {
|
|
24
|
+
return ctx.error(404, {
|
|
25
|
+
error_code: "package_release_not_found",
|
|
26
|
+
message: "Package release not found",
|
|
27
|
+
})
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return ctx.json({
|
|
31
|
+
ok: true,
|
|
32
|
+
package_release: publicMapPackageRelease(foundRelease),
|
|
33
|
+
})
|
|
34
|
+
})
|