Skip to content

Commit 82464e4

Browse files
feat: update API config CRUD to use visibility with input validation
POST/PUT validate visibility is one of public/unlisted/private. Default unlisted. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
1 parent 569eeb4 commit 82464e4

File tree

3 files changed

+20
-12
lines changed

3 files changed

+20
-12
lines changed

src/routes/api/configs/+server.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export const GET: RequestHandler = async ({ platform, cookies, request }) => {
1717
return json({ error: 'Rate limit exceeded' }, { status: 429, headers: { 'Retry-After': String(Math.ceil(rl.retryAfter! / 1000)) } });
1818
}
1919

20-
const { results } = await env.DB.prepare('SELECT id, slug, name, description, base_preset, is_public, alias, updated_at, snapshot, snapshot_at FROM configs WHERE user_id = ? ORDER BY updated_at DESC')
20+
const { results } = await env.DB.prepare('SELECT id, slug, name, description, base_preset, visibility, alias, updated_at, snapshot, snapshot_at FROM configs WHERE user_id = ? ORDER BY updated_at DESC')
2121
.bind(user.id)
2222
.all();
2323

@@ -43,7 +43,11 @@ export const POST: RequestHandler = async ({ platform, cookies, request }) => {
4343
return json({ error: 'Invalid request body' }, { status: 400 });
4444
}
4545

46-
const { name, description, base_preset, packages, custom_script, is_public, alias, dotfiles_repo, snapshot, snapshot_at } = body;
46+
const { name, description, base_preset, packages, custom_script, visibility, alias, dotfiles_repo, snapshot, snapshot_at } = body;
47+
48+
if (visibility !== undefined && !['public', 'unlisted', 'private'].includes(visibility)) {
49+
return json({ error: 'Invalid visibility. Must be public, unlisted, or private' }, { status: 400 });
50+
}
4751

4852
const rlKeyW = getRateLimitKey('config-write', user.id);
4953
const rlW = checkRateLimit(rlKeyW, RATE_LIMITS.CONFIG_WRITE);
@@ -92,11 +96,11 @@ export const POST: RequestHandler = async ({ platform, cookies, request }) => {
9296
try {
9397
await env.DB.prepare(
9498
`
95-
INSERT INTO configs (id, user_id, slug, name, description, base_preset, packages, custom_script, is_public, alias, dotfiles_repo, snapshot, snapshot_at)
99+
INSERT INTO configs (id, user_id, slug, name, description, base_preset, packages, custom_script, visibility, alias, dotfiles_repo, snapshot, snapshot_at)
96100
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
97101
`
98102
)
99-
.bind(id, user.id, slug, name, description || '', base_preset || 'developer', JSON.stringify(packages || []), custom_script || '', is_public !== false ? 1 : 0, cleanAlias, dotfiles_repo || '', snapshot ? JSON.stringify(snapshot) : null, snapshot_at || null)
103+
.bind(id, user.id, slug, name, description || '', base_preset || 'developer', JSON.stringify(packages || []), custom_script || '', visibility || 'unlisted', cleanAlias, dotfiles_repo || '', snapshot ? JSON.stringify(snapshot) : null, snapshot_at || null)
100104
.run();
101105
} catch (e) {
102106
console.error('POST /api/configs error:', e);

src/routes/api/configs/[slug]/+server.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,11 @@ export const PUT: RequestHandler = async ({ platform, cookies, params, request }
7070
return json({ error: 'Invalid request body' }, { status: 400 });
7171
}
7272

73-
const { name, description, base_preset, packages, custom_script, is_public, alias, dotfiles_repo, snapshot, snapshot_at } = body;
73+
const { name, description, base_preset, packages, custom_script, visibility, alias, dotfiles_repo, snapshot, snapshot_at } = body;
74+
75+
if (visibility !== undefined && !['public', 'unlisted', 'private'].includes(visibility)) {
76+
return json({ error: 'Invalid visibility. Must be public, unlisted, or private' }, { status: 400 });
77+
}
7478

7579
const rlKeyW = getRateLimitKey('config-write', user.id);
7680
const rlW = checkRateLimit(rlKeyW, RATE_LIMITS.CONFIG_WRITE);
@@ -127,7 +131,7 @@ export const PUT: RequestHandler = async ({ platform, cookies, params, request }
127131
base_preset = COALESCE(?, base_preset),
128132
packages = COALESCE(?, packages),
129133
custom_script = COALESCE(?, custom_script),
130-
is_public = COALESCE(?, is_public),
134+
visibility = COALESCE(?, visibility),
131135
alias = ?,
132136
dotfiles_repo = COALESCE(?, dotfiles_repo),
133137
snapshot = ?,
@@ -143,7 +147,7 @@ export const PUT: RequestHandler = async ({ platform, cookies, params, request }
143147
base_preset || null,
144148
packages ? JSON.stringify(packages) : null,
145149
custom_script !== undefined ? custom_script : null,
146-
is_public !== undefined ? (is_public ? 1 : 0) : null,
150+
visibility !== undefined ? visibility : null,
147151
newAlias,
148152
dotfiles_repo !== undefined ? dotfiles_repo : null,
149153
snapshot !== undefined ? (snapshot ? JSON.stringify(snapshot) : null) : null,

src/routes/api/configs/from-snapshot/+server.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ export const POST: RequestHandler = async ({ platform, cookies, request }) => {
5858
.run();
5959

6060
const updated = await env.DB.prepare(
61-
'SELECT id, slug, name, description, base_preset, packages, snapshot, snapshot_at, is_public FROM configs WHERE user_id = ? AND slug = ?'
62-
).bind(user.id, config_slug).first();
61+
'SELECT id, slug, name, description, base_preset, packages, snapshot, snapshot_at, visibility FROM configs WHERE user_id = ? AND slug = ?'
62+
).bind(user.id, config_slug).first();
6363

6464
return json({
6565
...updated,
@@ -96,8 +96,8 @@ export const POST: RequestHandler = async ({ platform, cookies, request }) => {
9696

9797
try {
9898
await env.DB.prepare(
99-
`INSERT INTO configs (id, user_id, slug, name, description, base_preset, packages, snapshot, snapshot_at, is_public)
100-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, datetime('now'), 1)`
99+
`INSERT INTO configs (id, user_id, slug, name, description, base_preset, packages, snapshot, snapshot_at, visibility)
100+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, datetime('now'), 'unlisted')`
101101
)
102102
.bind(
103103
id,
@@ -116,7 +116,7 @@ export const POST: RequestHandler = async ({ platform, cookies, request }) => {
116116
}
117117

118118
const created = await env.DB.prepare(
119-
'SELECT id, slug, name, description, base_preset, packages, snapshot, snapshot_at, is_public FROM configs WHERE id = ?'
119+
'SELECT id, slug, name, description, base_preset, packages, snapshot, snapshot_at, visibility FROM configs WHERE id = ?'
120120
).bind(id).first();
121121

122122
return json({

0 commit comments

Comments
 (0)