2022-01-08 18:13:56 +00:00
|
|
|
import axios from 'axios'
|
|
|
|
import { assertSuccessJsonResponse } from '../../assertSuccessJsonResponse'
|
|
|
|
import { z } from 'zod'
|
|
|
|
import { getDefaultTimeoutMilliseconds } from '../../getDefaultTimeoutMilliseconds'
|
2022-04-17 12:03:53 +00:00
|
|
|
import { NoMoreFeedsError } from '../NoMoreFeedsError'
|
|
|
|
import { FeedProviderMethod } from '../FeedProviderMethod'
|
2022-01-08 18:13:56 +00:00
|
|
|
|
|
|
|
const limit = 100
|
|
|
|
|
|
|
|
const emojiSchema = z.object({
|
|
|
|
name: z.string(),
|
|
|
|
url: z.string()
|
|
|
|
})
|
|
|
|
|
|
|
|
const schema = z.array(
|
|
|
|
z.object({
|
|
|
|
id: z.string(),
|
|
|
|
name: z.string().nullable(),
|
|
|
|
username: z.string(),
|
2022-01-08 18:25:44 +00:00
|
|
|
avatarUrl: z.string().nullable(),
|
2022-01-08 18:13:56 +00:00
|
|
|
isBot: z.boolean(),
|
|
|
|
emojis: z.array(emojiSchema),
|
|
|
|
createdAt: z.string(),
|
2022-01-08 18:25:44 +00:00
|
|
|
updatedAt: z.string().nullable(),
|
2022-01-08 18:13:56 +00:00
|
|
|
isLocked: z.boolean(),
|
|
|
|
description: z.string().nullable(),
|
|
|
|
location: z.string().nullable(),
|
|
|
|
birthday: z.string().nullable(),
|
|
|
|
lang: z.string().nullable(),
|
|
|
|
fields: z.array(
|
|
|
|
z.object({
|
|
|
|
name: z.string(),
|
|
|
|
value: z.string()
|
|
|
|
})
|
|
|
|
),
|
|
|
|
followersCount: z.number(),
|
|
|
|
followingCount: z.number(),
|
|
|
|
notesCount: z.number()
|
|
|
|
})
|
|
|
|
)
|
|
|
|
|
|
|
|
type Emoji = z.infer<typeof emojiSchema>
|
|
|
|
|
|
|
|
const replaceEmojis = (text: string, emojis: Emoji[]): string => {
|
|
|
|
emojis.forEach(emoji => {
|
|
|
|
text = text.replace(
|
|
|
|
RegExp(`:${emoji.name}:`, 'gi'),
|
|
|
|
`<img draggable="false" class="emoji" title="${emoji.name}" alt="${emoji.name}" src="${emoji.url}" />`
|
|
|
|
)
|
|
|
|
})
|
|
|
|
return text
|
|
|
|
}
|
|
|
|
|
|
|
|
const parseDescription = (description:string|null):string => {
|
|
|
|
if (typeof description !== 'string') {
|
|
|
|
return ''
|
|
|
|
}
|
|
|
|
return description.split('\n\n').map(paragraph => {
|
|
|
|
paragraph = paragraph.replace('\n', '</br>\n')
|
|
|
|
return `<p>${paragraph}</p>`
|
|
|
|
}).join('\n')
|
|
|
|
}
|
|
|
|
|
2022-04-17 12:03:53 +00:00
|
|
|
export const retrieveUsersPage:FeedProviderMethod = async (domain, page) => {
|
|
|
|
const response = await axios.post('https://' + domain + '/api/users', {
|
|
|
|
state: 'all',
|
|
|
|
origin: 'local',
|
|
|
|
sort: '+createdAt',
|
|
|
|
limit: limit,
|
|
|
|
offset: limit * page
|
|
|
|
}, {
|
|
|
|
timeout: getDefaultTimeoutMilliseconds()
|
|
|
|
})
|
|
|
|
assertSuccessJsonResponse(response)
|
|
|
|
const responseData = schema.parse(response.data)
|
|
|
|
if (responseData.length === 0) {
|
|
|
|
throw new NoMoreFeedsError('user')
|
2022-01-08 18:13:56 +00:00
|
|
|
}
|
2022-04-17 12:03:53 +00:00
|
|
|
return responseData.map(
|
|
|
|
item => {
|
|
|
|
return {
|
|
|
|
name: item.username,
|
|
|
|
displayName: replaceEmojis(item.name ?? item.username, item.emojis),
|
|
|
|
description: replaceEmojis(parseDescription(item.description ?? ''), item.emojis),
|
|
|
|
followersCount: item.followersCount,
|
|
|
|
followingCount: item.followingCount,
|
|
|
|
statusesCount: item.notesCount,
|
|
|
|
bot: item.isBot,
|
|
|
|
url: `https://${domain}/@${item.username}`,
|
|
|
|
avatar: item.avatarUrl,
|
|
|
|
locked: item.isLocked,
|
2022-09-14 19:16:04 +00:00
|
|
|
lastStatusAt: item.updatedAt !== null ? new Date(item.updatedAt) : undefined,
|
2022-04-17 12:03:53 +00:00
|
|
|
createdAt: new Date(item.createdAt),
|
|
|
|
fields: [
|
|
|
|
...item.fields.map(field => {
|
|
|
|
return {
|
|
|
|
name: replaceEmojis(field.name, item.emojis),
|
|
|
|
value: replaceEmojis(field.value, item.emojis),
|
2022-09-14 19:16:04 +00:00
|
|
|
verifiedAt: undefined
|
2022-04-17 12:03:53 +00:00
|
|
|
}
|
|
|
|
}),
|
|
|
|
...[
|
2022-09-14 19:16:04 +00:00
|
|
|
{ name: 'Location', value: item.location, verifiedAt: undefined },
|
|
|
|
{ name: 'Birthday', value: item.birthday, verifiedAt: undefined },
|
|
|
|
{ name: 'Language', value: item.lang, verifiedAt: undefined }
|
2022-04-17 12:03:53 +00:00
|
|
|
].filter(field => field.value !== null)
|
|
|
|
],
|
|
|
|
type: 'account',
|
2022-09-14 19:16:04 +00:00
|
|
|
parentFeed: undefined
|
2022-04-17 12:03:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
2022-01-08 18:13:56 +00:00
|
|
|
}
|