-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
add database entries for new gists, update REPL URLs #2680
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
a4f7954
fd1b444
c3857ab
9795ee8
f6fd1e2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
import send from '@polka/send'; | ||
import redirect from '@polka/redirect'; | ||
import body from '../_utils/body.js'; | ||
import * as httpie from 'httpie'; | ||
import { query, find } from '../../../utils/db'; | ||
import { isUser } from '../../../backend/auth'; | ||
import { get_example } from '../../examples/_examples.js'; | ||
|
||
const { GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET } = process.env; | ||
|
||
async function import_gist(req, res) { | ||
const base = `https://api.github.com/gists/${req.params.id}`; | ||
const url = `${base}?client_id=${GITHUB_CLIENT_ID}&client_secret=${GITHUB_CLIENT_SECRET}`; | ||
|
||
try { | ||
const { data } = await httpie.get(url, { | ||
headers: { | ||
'User-Agent': 'https://svelte.dev' | ||
} | ||
}); | ||
|
||
// create owner if necessary... | ||
let user = await find(`select * from users where uid = $1`, [data.owner.id]); | ||
|
||
if (!user) { | ||
const { id, name, login, avatar_url } = data.owner; | ||
|
||
[user] = await query(` | ||
insert into users(uid, name, username, avatar) | ||
values ($1, $2, $3, $4) | ||
returning * | ||
`, [id, name, login, avatar_url]); | ||
} | ||
|
||
delete data.files['README.md']; | ||
delete data.files['meta.json']; | ||
|
||
const files = Object.keys(data.files).map(key => { | ||
const name = key.replace(/\.html$/, '.svelte'); | ||
|
||
return { | ||
name, | ||
source: data.files[key].content | ||
}; | ||
}); | ||
|
||
// add gist to database... | ||
const [gist] = await query(` | ||
insert into gists(uid, user_id, name, files) | ||
values ($1, $2, $3, $4) returning *`, [req.params.id, user.id, data.description, JSON.stringify(files)]); | ||
|
||
send(res, 200, { | ||
uid: req.params.id, | ||
name: data.description, | ||
files, | ||
owner: data.owner.id | ||
}); | ||
} catch (err) { | ||
send(res, err.statusCode, { error: err.message }); | ||
} | ||
} | ||
|
||
export async function get(req, res) { | ||
// is this an example? | ||
const example = get_example(req.params.id); | ||
|
||
if (example) { | ||
return send(res, 200, { | ||
relaxed: true, | ||
uid: req.params.id, | ||
name: example.title, | ||
files: example.files, | ||
owner: null | ||
}); | ||
} | ||
|
||
const [row] = await query(` | ||
select g.*, u.uid as owner from gists g | ||
left join users u on g.user_id = u.id | ||
where g.uid = $1 limit 1 | ||
`, [req.params.id]); // via filename pattern | ||
|
||
if (!row) { | ||
return import_gist(req, res); | ||
} | ||
|
||
send(res, 200, { | ||
uid: row.uid.replace(/-/g, ''), | ||
name: row.name, | ||
files: row.files, | ||
owner: row.owner | ||
}); | ||
} | ||
|
||
export async function patch(req, res) { | ||
const user = await isUser(req, res); | ||
if (!user) return; // response already sent | ||
|
||
let id, uid=req.params.id; | ||
|
||
try { | ||
const [row] = await query(`select * from gists where uid = $1 limit 1`, [uid]); | ||
if (!row) return send(res, 404, { error: 'Gist not found' }); | ||
if (row.user_id !== user.id) return send(res, 403, { error: 'Item does not belong to you' }); | ||
id = row.id; | ||
} catch (err) { | ||
console.error('PATCH /gists @ select', err); | ||
return send(res, 500); | ||
} | ||
|
||
try { | ||
const obj = await body(req); | ||
obj.updated_at = 'now()'; | ||
let k, cols=[], vals=[]; | ||
for (k in obj) { | ||
cols.push(k); | ||
vals.push(k === 'files' ? JSON.stringify(obj[k]) : obj[k]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did I write this? Can't tell if this file was moved or is new. Looking at it, the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, then okay. Arrays need explicit casting. We could also do There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah, i wondered about that. i reckon explicit casting is ok, since we probably won't need to add it in more places, and since we'll get a loud error if we do There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I happy either way |
||
} | ||
|
||
const tmp = vals.map((x, i) => `$${i + 1}`).join(','); | ||
const set = `set (${cols.join(',')}) = (${tmp})`; | ||
|
||
const [row] = await query(`update gists ${set} where id = ${id} returning *`, vals); | ||
|
||
send(res, 200, { | ||
uid: row.uid.replace(/-/g, ''), | ||
name: row.name, | ||
files: row.files, | ||
owner: user.uid, | ||
}); | ||
} catch (err) { | ||
console.error('PATCH /gists @ update', err); | ||
send(res, 500, { error: err.message }); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be the only change to the production DB required
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done