Skip to content

Commit 1c4ecd2

Browse files
committed
feat(configs): add snapshot upload endpoint for CLI
1 parent 3724732 commit 1c4ecd2

File tree

1 file changed

+115
-0
lines changed

1 file changed

+115
-0
lines changed
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import { json } from '@sveltejs/kit';
2+
import type { RequestHandler } from './$types';
3+
import { getCurrentUser, slugify, generateId } from '$lib/server/auth';
4+
5+
export const POST: RequestHandler = async ({ platform, cookies, request }) => {
6+
const env = platform?.env;
7+
if (!env) return json({ error: 'Platform env not available' }, { status: 500 });
8+
9+
const user = await getCurrentUser(request, cookies, env.DB, env.JWT_SECRET);
10+
if (!user) return json({ error: 'Unauthorized' }, { status: 401 });
11+
12+
let body;
13+
try {
14+
body = await request.json();
15+
} catch {
16+
return json({ error: 'Invalid request body' }, { status: 400 });
17+
}
18+
19+
const { name, description, snapshot, config_slug } = body;
20+
21+
if (!name) return json({ error: 'Name is required' }, { status: 400 });
22+
if (!snapshot) return json({ error: 'Snapshot is required' }, { status: 400 });
23+
24+
const packages = snapshot.catalog_match?.matched || [];
25+
const base_preset = snapshot.matched_preset || 'developer';
26+
27+
if (config_slug) {
28+
const existing = await env.DB.prepare(
29+
'SELECT * FROM configs WHERE user_id = ? AND slug = ?'
30+
).bind(user.id, config_slug).first();
31+
32+
if (!existing) {
33+
return json({ error: 'Config not found' }, { status: 404 });
34+
}
35+
36+
await env.DB.prepare(
37+
`UPDATE configs
38+
SET snapshot = ?, snapshot_at = datetime('now'), packages = ?
39+
WHERE user_id = ? AND slug = ?`
40+
)
41+
.bind(
42+
JSON.stringify(snapshot),
43+
JSON.stringify(packages),
44+
user.id,
45+
config_slug
46+
)
47+
.run();
48+
49+
const updated = await env.DB.prepare(
50+
'SELECT id, slug, name, description, base_preset, packages, snapshot, snapshot_at, is_public FROM configs WHERE user_id = ? AND slug = ?'
51+
).bind(user.id, config_slug).first();
52+
53+
return json({
54+
...updated,
55+
snapshot: JSON.parse((updated as any).snapshot),
56+
packages: JSON.parse((updated as any).packages)
57+
});
58+
}
59+
60+
const configCount = await env.DB.prepare(
61+
'SELECT COUNT(*) as count FROM configs WHERE user_id = ?'
62+
).bind(user.id).first<{ count: number }>();
63+
64+
if (configCount && configCount.count >= 20) {
65+
return json({ error: 'Maximum 20 configs per user' }, { status: 400 });
66+
}
67+
68+
let slug = slugify(name);
69+
if (!slug) return json({ error: 'Invalid name' }, { status: 400 });
70+
71+
let finalSlug = slug;
72+
let suffix = 2;
73+
while (true) {
74+
const existing = await env.DB.prepare(
75+
'SELECT id FROM configs WHERE user_id = ? AND slug = ?'
76+
).bind(user.id, finalSlug).first();
77+
78+
if (!existing) break;
79+
80+
finalSlug = `${slug}-${suffix}`;
81+
suffix++;
82+
}
83+
84+
const id = generateId();
85+
86+
try {
87+
await env.DB.prepare(
88+
`INSERT INTO configs (id, user_id, slug, name, description, base_preset, packages, snapshot, snapshot_at, is_public)
89+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, datetime('now'), 1)`
90+
)
91+
.bind(
92+
id,
93+
user.id,
94+
finalSlug,
95+
name,
96+
description || '',
97+
base_preset,
98+
JSON.stringify(packages),
99+
JSON.stringify(snapshot)
100+
)
101+
.run();
102+
} catch (e) {
103+
return json({ error: 'Database error: ' + (e as Error).message }, { status: 500 });
104+
}
105+
106+
const created = await env.DB.prepare(
107+
'SELECT id, slug, name, description, base_preset, packages, snapshot, snapshot_at, is_public FROM configs WHERE id = ?'
108+
).bind(id).first();
109+
110+
return json({
111+
...created,
112+
snapshot: JSON.parse((created as any).snapshot),
113+
packages: JSON.parse((created as any).packages)
114+
}, { status: 201 });
115+
};

0 commit comments

Comments
 (0)