view single tag

pull/274/head
Sven Sauleau 2023-02-13 12:13:54 +00:00
rodzic 36732ad0cd
commit d8e22705e6
5 zmienionych plików z 92 dodań i 0 usunięć

Wyświetl plik

@ -46,6 +46,10 @@ export function mediaNotFound(id: string): Response {
return generateErrorResponse('Resource not found', 404, `Media "${id}" not found`)
}
export function tagNotFound(tag: string): Response {
return generateErrorResponse('Resource not found', 404, `Tag "${tag}" not found`)
}
export function exceededLimit(detail: string): Response {
return generateErrorResponse('Limit exceeded', 400, detail)
}

Wyświetl plik

@ -1,4 +1,5 @@
import type { Note } from 'wildebeest/backend/src/activitypub/objects/note'
import type { Tag } from 'wildebeest/backend/src/types/tag'
export type Hashtag = string
@ -27,3 +28,23 @@ export async function insertHashtags(db: D1Database, note: Note, values: Array<H
await db.batch(queries)
}
export async function getTag(db: D1Database, domain: string, tag: string): Promise<Tag | null> {
const query = `
SELECT * FROM note_hashtags WHERE value=?
`
const { results, success, error } = await db.prepare(query).bind(tag).all<{ value: string }>()
if (!success) {
throw new Error('SQL error: ' + error)
}
if (!results || results.length === 0) {
return null
}
return {
name: results[0].value,
url: new URL(`/tags/${results[0].value}`, `https://${domain}`),
history: [],
}
}

Wyświetl plik

@ -0,0 +1,6 @@
export type Tag = {
name: string
url: URL
history: Array<void>
following?: boolean
}

Wyświetl plik

@ -0,0 +1,36 @@
import { strict as assert } from 'node:assert/strict'
import { createPerson } from 'wildebeest/backend/src/activitypub/actors'
import { createPublicNote } from 'wildebeest/backend/src/activitypub/objects/note'
import { makeDB, assertCORS, isUrlValid } from '../utils'
import * as tag_id from 'wildebeest/functions/api/v1/tags/[tag]'
import { insertHashtags } from 'wildebeest/backend/src/mastodon/hashtag'
const domain = 'cloudflare.com'
const userKEK = 'test_kek20'
describe('Mastodon APIs', () => {
describe('tags', () => {
test('return 404 when non existent tag', async () => {
const db = await makeDB()
const res = await tag_id.handleRequestGet(db, domain, 'non-existent-tag')
assertCORS(res)
assert.equal(res.status, 404)
})
test('return tag', async () => {
const db = await makeDB()
const actor = await createPerson(domain, db, userKEK, 'sven@cloudflare.com')
const note = await createPublicNote(domain, db, 'my localnote status', actor)
await insertHashtags(db, note, ['test'])
const res = await tag_id.handleRequestGet(db, domain, 'test')
assertCORS(res)
assert.equal(res.status, 200)
const data = await res.json<any>()
assert.equal(data.name, 'test')
assert(isUrlValid(data.url))
})
})
})

Wyświetl plik

@ -0,0 +1,25 @@
// https://docs.joinmastodon.org/methods/tags/#get
import type { ContextData } from 'wildebeest/backend/src/types/context'
import type { Env } from 'wildebeest/backend/src/types/env'
import { getTag } from 'wildebeest/backend/src/mastodon/hashtag'
import * as errors from 'wildebeest/backend/src/errors'
import { cors } from 'wildebeest/backend/src/utils/cors'
const headers = {
...cors(),
'content-type': 'application/json',
} as const
export const onRequestGet: PagesFunction<Env, any, ContextData> = async ({ params, env, request }) => {
const domain = new URL(request.url).hostname
return handleRequestGet(env.DATABASE, domain, params.tag as string)
}
export async function handleRequestGet(db: D1Database, domain: string, value: string): Promise<Response> {
const tag = await getTag(db, domain, value)
if (tag === null) {
return errors.tagNotFound(value)
}
return new Response(JSON.stringify(tag), { headers })
}