Add describeFeedGenerator route + multiple feeds (#19)
* describeFeedGenerator route + multiple feeds * tweak readme
This commit is contained in:
parent
285ef14a68
commit
3606414b79
@ -36,11 +36,11 @@ Next you will need to do two things:
|
||||
|
||||
This will subscribe to the repo subscription stream on startup, parse events & index them according to your provided logic.
|
||||
|
||||
2. Implement feed generation logic in `src/feed-generation.ts`
|
||||
|
||||
The types are in place and you will just need to return something that satisfies the `SkeletonFeedPost[]` type.
|
||||
2. Implement feed generation logic in `src/algos`
|
||||
|
||||
For inspiration, we've provided a very simple feed algorithm ("whats alf") that returns all posts related to the titular character of the TV show ALF.
|
||||
For inspiration, we've provided a very simple feed algorithm (`whats-alf`) that returns all posts related to the titular character of the TV show ALF.
|
||||
|
||||
You can either edit it or add another algorithm alongside it. The types are in place an dyou will just need to return something that satisfies the `SkeletonFeedPost[]` type.
|
||||
|
||||
We've taken care of setting this server up with a did:web. However, you're free to switch this out for did:plc if you like - you may want to if you expect this Feed Generator to be long-standing and possibly migrating domains.
|
||||
|
||||
|
14
src/algos/index.ts
Normal file
14
src/algos/index.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { AppContext } from '../config'
|
||||
import {
|
||||
QueryParams,
|
||||
OutputSchema as AlgoOutput,
|
||||
} from '../lexicon/types/app/bsky/feed/getFeedSkeleton'
|
||||
import * as whatsAlf from './whats-alf'
|
||||
|
||||
type AlgoHandler = (ctx: AppContext, params: QueryParams) => Promise<AlgoOutput>
|
||||
|
||||
const algos: Record<string, AlgoHandler> = {
|
||||
[whatsAlf.uri]: whatsAlf.handler,
|
||||
}
|
||||
|
||||
export default algos
|
42
src/algos/whats-alf.ts
Normal file
42
src/algos/whats-alf.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import { InvalidRequestError } from '@atproto/xrpc-server'
|
||||
import { QueryParams } from '../lexicon/types/app/bsky/feed/getFeedSkeleton'
|
||||
import { AppContext } from '../config'
|
||||
|
||||
export const uri = 'at://did:example:alice/app.bsky.feed.generator/whats-alf'
|
||||
|
||||
export const handler = async (ctx: AppContext, params: QueryParams) => {
|
||||
let builder = ctx.db
|
||||
.selectFrom('post')
|
||||
.selectAll()
|
||||
.orderBy('indexedAt', 'desc')
|
||||
.orderBy('cid', 'desc')
|
||||
.limit(params.limit)
|
||||
|
||||
if (params.cursor) {
|
||||
const [indexedAt, cid] = params.cursor.split('::')
|
||||
if (!indexedAt || !cid) {
|
||||
throw new InvalidRequestError('malformed cursor')
|
||||
}
|
||||
const timeStr = new Date(parseInt(indexedAt, 10)).toISOString()
|
||||
builder = builder
|
||||
.where('post.indexedAt', '<', timeStr)
|
||||
.orWhere((qb) => qb.where('post.indexedAt', '=', timeStr))
|
||||
.where('post.cid', '<', cid)
|
||||
}
|
||||
const res = await builder.execute()
|
||||
|
||||
const feed = res.map((row) => ({
|
||||
post: row.uri,
|
||||
}))
|
||||
|
||||
let cursor: string | undefined
|
||||
const last = res.at(-1)
|
||||
if (last) {
|
||||
cursor = `${new Date(last.indexedAt).getTime()}::${last.cid}`
|
||||
}
|
||||
|
||||
return {
|
||||
cursor,
|
||||
feed,
|
||||
}
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
import { InvalidRequestError } from '@atproto/xrpc-server'
|
||||
import { Server } from './lexicon'
|
||||
import { AppContext } from './config'
|
||||
import { validateAuth } from './auth'
|
||||
|
||||
export default function (server: Server, ctx: AppContext) {
|
||||
server.app.bsky.feed.getFeedSkeleton(async ({ params, req }) => {
|
||||
if (
|
||||
params.feed !== 'at://did:example:alice/app.bsky.feed.generator/whats-alf'
|
||||
) {
|
||||
throw new InvalidRequestError(
|
||||
'Unsupported algorithm',
|
||||
'UnsupportedAlgorithm',
|
||||
)
|
||||
}
|
||||
/**
|
||||
* Example of how to check auth if giving user-specific results:
|
||||
*
|
||||
* const requesterDid = await validateAuth(
|
||||
* req,
|
||||
* ctx.cfg.serviceDid,
|
||||
* ctx.didResolver,
|
||||
* )
|
||||
*/
|
||||
|
||||
let builder = ctx.db
|
||||
.selectFrom('post')
|
||||
.selectAll()
|
||||
.orderBy('indexedAt', 'desc')
|
||||
.orderBy('cid', 'desc')
|
||||
.limit(params.limit)
|
||||
|
||||
if (params.cursor) {
|
||||
const [indexedAt, cid] = params.cursor.split('::')
|
||||
if (!indexedAt || !cid) {
|
||||
throw new InvalidRequestError('malformed cursor')
|
||||
}
|
||||
const timeStr = new Date(parseInt(indexedAt, 10)).toISOString()
|
||||
builder = builder
|
||||
.where('post.indexedAt', '<', timeStr)
|
||||
.orWhere((qb) => qb.where('post.indexedAt', '=', timeStr))
|
||||
.where('post.cid', '<', cid)
|
||||
}
|
||||
const res = await builder.execute()
|
||||
|
||||
const feed = res.map((row) => ({
|
||||
post: row.uri,
|
||||
}))
|
||||
|
||||
let cursor: string | undefined
|
||||
const last = res.at(-1)
|
||||
if (last) {
|
||||
cursor = `${new Date(last.indexedAt).getTime()}::${last.cid}`
|
||||
}
|
||||
|
||||
return {
|
||||
encoding: 'application/json',
|
||||
body: {
|
||||
cursor,
|
||||
feed,
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
@ -67,23 +67,27 @@ import * as ComAtprotoSyncListRepos from './types/com/atproto/sync/listRepos'
|
||||
import * as ComAtprotoSyncNotifyOfUpdate from './types/com/atproto/sync/notifyOfUpdate'
|
||||
import * as ComAtprotoSyncRequestCrawl from './types/com/atproto/sync/requestCrawl'
|
||||
import * as ComAtprotoSyncSubscribeRepos from './types/com/atproto/sync/subscribeRepos'
|
||||
import * as AppBskyActorGetPreferences from './types/app/bsky/actor/getPreferences'
|
||||
import * as AppBskyActorGetProfile from './types/app/bsky/actor/getProfile'
|
||||
import * as AppBskyActorGetProfiles from './types/app/bsky/actor/getProfiles'
|
||||
import * as AppBskyActorGetSuggestions from './types/app/bsky/actor/getSuggestions'
|
||||
import * as AppBskyActorPutPreferences from './types/app/bsky/actor/putPreferences'
|
||||
import * as AppBskyActorSearchActors from './types/app/bsky/actor/searchActors'
|
||||
import * as AppBskyActorSearchActorsTypeahead from './types/app/bsky/actor/searchActorsTypeahead'
|
||||
import * as AppBskyFeedBookmarkFeed from './types/app/bsky/feed/bookmarkFeed'
|
||||
import * as AppBskyFeedDescribeFeedGenerator from './types/app/bsky/feed/describeFeedGenerator'
|
||||
import * as AppBskyFeedGetActorFeeds from './types/app/bsky/feed/getActorFeeds'
|
||||
import * as AppBskyFeedGetAuthorFeed from './types/app/bsky/feed/getAuthorFeed'
|
||||
import * as AppBskyFeedGetBookmarkedFeeds from './types/app/bsky/feed/getBookmarkedFeeds'
|
||||
import * as AppBskyFeedGetFeed from './types/app/bsky/feed/getFeed'
|
||||
import * as AppBskyFeedGetFeedGenerator from './types/app/bsky/feed/getFeedGenerator'
|
||||
import * as AppBskyFeedGetFeedSkeleton from './types/app/bsky/feed/getFeedSkeleton'
|
||||
import * as AppBskyFeedGetLikes from './types/app/bsky/feed/getLikes'
|
||||
import * as AppBskyFeedGetPostThread from './types/app/bsky/feed/getPostThread'
|
||||
import * as AppBskyFeedGetPosts from './types/app/bsky/feed/getPosts'
|
||||
import * as AppBskyFeedGetRepostedBy from './types/app/bsky/feed/getRepostedBy'
|
||||
import * as AppBskyFeedGetSavedFeeds from './types/app/bsky/feed/getSavedFeeds'
|
||||
import * as AppBskyFeedGetTimeline from './types/app/bsky/feed/getTimeline'
|
||||
import * as AppBskyFeedUnbookmarkFeed from './types/app/bsky/feed/unbookmarkFeed'
|
||||
import * as AppBskyFeedSaveFeed from './types/app/bsky/feed/saveFeed'
|
||||
import * as AppBskyFeedUnsaveFeed from './types/app/bsky/feed/unsaveFeed'
|
||||
import * as AppBskyGraphGetBlocks from './types/app/bsky/graph/getBlocks'
|
||||
import * as AppBskyGraphGetFollowers from './types/app/bsky/graph/getFollowers'
|
||||
import * as AppBskyGraphGetFollows from './types/app/bsky/graph/getFollows'
|
||||
@ -730,6 +734,13 @@ export class ActorNS {
|
||||
this._server = server
|
||||
}
|
||||
|
||||
getPreferences<AV extends AuthVerifier>(
|
||||
cfg: ConfigOf<AV, AppBskyActorGetPreferences.Handler<ExtractAuth<AV>>>,
|
||||
) {
|
||||
const nsid = 'app.bsky.actor.getPreferences' // @ts-ignore
|
||||
return this._server.xrpc.method(nsid, cfg)
|
||||
}
|
||||
|
||||
getProfile<AV extends AuthVerifier>(
|
||||
cfg: ConfigOf<AV, AppBskyActorGetProfile.Handler<ExtractAuth<AV>>>,
|
||||
) {
|
||||
@ -751,6 +762,13 @@ export class ActorNS {
|
||||
return this._server.xrpc.method(nsid, cfg)
|
||||
}
|
||||
|
||||
putPreferences<AV extends AuthVerifier>(
|
||||
cfg: ConfigOf<AV, AppBskyActorPutPreferences.Handler<ExtractAuth<AV>>>,
|
||||
) {
|
||||
const nsid = 'app.bsky.actor.putPreferences' // @ts-ignore
|
||||
return this._server.xrpc.method(nsid, cfg)
|
||||
}
|
||||
|
||||
searchActors<AV extends AuthVerifier>(
|
||||
cfg: ConfigOf<AV, AppBskyActorSearchActors.Handler<ExtractAuth<AV>>>,
|
||||
) {
|
||||
@ -784,10 +802,13 @@ export class FeedNS {
|
||||
this._server = server
|
||||
}
|
||||
|
||||
bookmarkFeed<AV extends AuthVerifier>(
|
||||
cfg: ConfigOf<AV, AppBskyFeedBookmarkFeed.Handler<ExtractAuth<AV>>>,
|
||||
describeFeedGenerator<AV extends AuthVerifier>(
|
||||
cfg: ConfigOf<
|
||||
AV,
|
||||
AppBskyFeedDescribeFeedGenerator.Handler<ExtractAuth<AV>>
|
||||
>,
|
||||
) {
|
||||
const nsid = 'app.bsky.feed.bookmarkFeed' // @ts-ignore
|
||||
const nsid = 'app.bsky.feed.describeFeedGenerator' // @ts-ignore
|
||||
return this._server.xrpc.method(nsid, cfg)
|
||||
}
|
||||
|
||||
@ -805,13 +826,6 @@ export class FeedNS {
|
||||
return this._server.xrpc.method(nsid, cfg)
|
||||
}
|
||||
|
||||
getBookmarkedFeeds<AV extends AuthVerifier>(
|
||||
cfg: ConfigOf<AV, AppBskyFeedGetBookmarkedFeeds.Handler<ExtractAuth<AV>>>,
|
||||
) {
|
||||
const nsid = 'app.bsky.feed.getBookmarkedFeeds' // @ts-ignore
|
||||
return this._server.xrpc.method(nsid, cfg)
|
||||
}
|
||||
|
||||
getFeed<AV extends AuthVerifier>(
|
||||
cfg: ConfigOf<AV, AppBskyFeedGetFeed.Handler<ExtractAuth<AV>>>,
|
||||
) {
|
||||
@ -819,6 +833,13 @@ export class FeedNS {
|
||||
return this._server.xrpc.method(nsid, cfg)
|
||||
}
|
||||
|
||||
getFeedGenerator<AV extends AuthVerifier>(
|
||||
cfg: ConfigOf<AV, AppBskyFeedGetFeedGenerator.Handler<ExtractAuth<AV>>>,
|
||||
) {
|
||||
const nsid = 'app.bsky.feed.getFeedGenerator' // @ts-ignore
|
||||
return this._server.xrpc.method(nsid, cfg)
|
||||
}
|
||||
|
||||
getFeedSkeleton<AV extends AuthVerifier>(
|
||||
cfg: ConfigOf<AV, AppBskyFeedGetFeedSkeleton.Handler<ExtractAuth<AV>>>,
|
||||
) {
|
||||
@ -854,6 +875,13 @@ export class FeedNS {
|
||||
return this._server.xrpc.method(nsid, cfg)
|
||||
}
|
||||
|
||||
getSavedFeeds<AV extends AuthVerifier>(
|
||||
cfg: ConfigOf<AV, AppBskyFeedGetSavedFeeds.Handler<ExtractAuth<AV>>>,
|
||||
) {
|
||||
const nsid = 'app.bsky.feed.getSavedFeeds' // @ts-ignore
|
||||
return this._server.xrpc.method(nsid, cfg)
|
||||
}
|
||||
|
||||
getTimeline<AV extends AuthVerifier>(
|
||||
cfg: ConfigOf<AV, AppBskyFeedGetTimeline.Handler<ExtractAuth<AV>>>,
|
||||
) {
|
||||
@ -861,10 +889,17 @@ export class FeedNS {
|
||||
return this._server.xrpc.method(nsid, cfg)
|
||||
}
|
||||
|
||||
unbookmarkFeed<AV extends AuthVerifier>(
|
||||
cfg: ConfigOf<AV, AppBskyFeedUnbookmarkFeed.Handler<ExtractAuth<AV>>>,
|
||||
saveFeed<AV extends AuthVerifier>(
|
||||
cfg: ConfigOf<AV, AppBskyFeedSaveFeed.Handler<ExtractAuth<AV>>>,
|
||||
) {
|
||||
const nsid = 'app.bsky.feed.unbookmarkFeed' // @ts-ignore
|
||||
const nsid = 'app.bsky.feed.saveFeed' // @ts-ignore
|
||||
return this._server.xrpc.method(nsid, cfg)
|
||||
}
|
||||
|
||||
unsaveFeed<AV extends AuthVerifier>(
|
||||
cfg: ConfigOf<AV, AppBskyFeedUnsaveFeed.Handler<ExtractAuth<AV>>>,
|
||||
) {
|
||||
const nsid = 'app.bsky.feed.unsaveFeed' // @ts-ignore
|
||||
return this._server.xrpc.method(nsid, cfg)
|
||||
}
|
||||
}
|
||||
|
@ -835,6 +835,15 @@ export const schemaDict = {
|
||||
resolved: {
|
||||
type: 'boolean',
|
||||
},
|
||||
actionType: {
|
||||
type: 'string',
|
||||
knownValues: [
|
||||
'com.atproto.admin.defs#takedown',
|
||||
'com.atproto.admin.defs#flag',
|
||||
'com.atproto.admin.defs#acknowledge',
|
||||
'com.atproto.admin.defs#escalate',
|
||||
],
|
||||
},
|
||||
limit: {
|
||||
type: 'integer',
|
||||
minimum: 1,
|
||||
@ -2114,6 +2123,10 @@ export const schemaDict = {
|
||||
type: 'string',
|
||||
format: 'handle',
|
||||
},
|
||||
did: {
|
||||
type: 'string',
|
||||
format: 'did',
|
||||
},
|
||||
inviteCode: {
|
||||
type: 'string',
|
||||
},
|
||||
@ -2165,6 +2178,12 @@ export const schemaDict = {
|
||||
{
|
||||
name: 'UnsupportedDomain',
|
||||
},
|
||||
{
|
||||
name: 'UnresolvableDid',
|
||||
},
|
||||
{
|
||||
name: 'IncompatibleDidDoc',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
@ -3509,6 +3528,66 @@ export const schemaDict = {
|
||||
},
|
||||
},
|
||||
},
|
||||
preferences: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'union',
|
||||
refs: [
|
||||
'lex:app.bsky.actor.defs#adultContentPref',
|
||||
'lex:app.bsky.actor.defs#contentLabelPref',
|
||||
],
|
||||
},
|
||||
},
|
||||
adultContentPref: {
|
||||
type: 'object',
|
||||
required: ['enabled'],
|
||||
properties: {
|
||||
enabled: {
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
contentLabelPref: {
|
||||
type: 'object',
|
||||
required: ['label', 'visibility'],
|
||||
properties: {
|
||||
label: {
|
||||
type: 'string',
|
||||
},
|
||||
visibility: {
|
||||
type: 'string',
|
||||
knownValues: ['show', 'warn', 'hide'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
AppBskyActorGetPreferences: {
|
||||
lexicon: 1,
|
||||
id: 'app.bsky.actor.getPreferences',
|
||||
defs: {
|
||||
main: {
|
||||
type: 'query',
|
||||
description: 'Get private preferences attached to the account.',
|
||||
parameters: {
|
||||
type: 'params',
|
||||
properties: {},
|
||||
},
|
||||
output: {
|
||||
encoding: 'application/json',
|
||||
schema: {
|
||||
type: 'object',
|
||||
required: ['preferences'],
|
||||
properties: {
|
||||
preferences: {
|
||||
type: 'ref',
|
||||
ref: 'lex:app.bsky.actor.defs#preferences',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
AppBskyActorGetProfile: {
|
||||
@ -3655,6 +3734,29 @@ export const schemaDict = {
|
||||
},
|
||||
},
|
||||
},
|
||||
AppBskyActorPutPreferences: {
|
||||
lexicon: 1,
|
||||
id: 'app.bsky.actor.putPreferences',
|
||||
defs: {
|
||||
main: {
|
||||
type: 'procedure',
|
||||
description: 'Sets the private preferences attached to the account.',
|
||||
input: {
|
||||
encoding: 'application/json',
|
||||
schema: {
|
||||
type: 'object',
|
||||
required: ['preferences'],
|
||||
properties: {
|
||||
preferences: {
|
||||
type: 'ref',
|
||||
ref: 'lex:app.bsky.actor.defs#preferences',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
AppBskyActorSearchActors: {
|
||||
lexicon: 1,
|
||||
id: 'app.bsky.actor.searchActors',
|
||||
@ -3899,6 +4001,7 @@ export const schemaDict = {
|
||||
'lex:app.bsky.embed.record#viewRecord',
|
||||
'lex:app.bsky.embed.record#viewNotFound',
|
||||
'lex:app.bsky.embed.record#viewBlocked',
|
||||
'lex:app.bsky.feed.defs#generatorView',
|
||||
],
|
||||
},
|
||||
},
|
||||
@ -4008,29 +4111,6 @@ export const schemaDict = {
|
||||
},
|
||||
},
|
||||
},
|
||||
AppBskyFeedBookmarkFeed: {
|
||||
lexicon: 1,
|
||||
id: 'app.bsky.feed.bookmarkFeed',
|
||||
defs: {
|
||||
main: {
|
||||
type: 'procedure',
|
||||
description: 'Bookmark a 3rd party feed for use across clients',
|
||||
input: {
|
||||
encoding: 'application/json',
|
||||
schema: {
|
||||
type: 'object',
|
||||
required: ['feed'],
|
||||
properties: {
|
||||
feed: {
|
||||
type: 'string',
|
||||
format: 'at-uri',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
AppBskyFeedDefs: {
|
||||
lexicon: 1,
|
||||
id: 'app.bsky.feed.defs',
|
||||
@ -4215,12 +4295,16 @@ export const schemaDict = {
|
||||
},
|
||||
generatorView: {
|
||||
type: 'object',
|
||||
required: ['uri', 'creator', 'indexedAt'],
|
||||
required: ['uri', 'cid', 'creator', 'indexedAt'],
|
||||
properties: {
|
||||
uri: {
|
||||
type: 'string',
|
||||
format: 'at-uri',
|
||||
},
|
||||
cid: {
|
||||
type: 'string',
|
||||
format: 'cid',
|
||||
},
|
||||
did: {
|
||||
type: 'string',
|
||||
format: 'did',
|
||||
@ -4247,6 +4331,10 @@ export const schemaDict = {
|
||||
avatar: {
|
||||
type: 'string',
|
||||
},
|
||||
likeCount: {
|
||||
type: 'integer',
|
||||
minimum: 0,
|
||||
},
|
||||
viewer: {
|
||||
type: 'ref',
|
||||
ref: 'lex:app.bsky.feed.defs#generatorViewerState',
|
||||
@ -4260,7 +4348,7 @@ export const schemaDict = {
|
||||
generatorViewerState: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
subscribed: {
|
||||
saved: {
|
||||
type: 'boolean',
|
||||
},
|
||||
like: {
|
||||
@ -4295,6 +4383,62 @@ export const schemaDict = {
|
||||
},
|
||||
},
|
||||
},
|
||||
AppBskyFeedDescribeFeedGenerator: {
|
||||
lexicon: 1,
|
||||
id: 'app.bsky.feed.describeFeedGenerator',
|
||||
defs: {
|
||||
main: {
|
||||
type: 'query',
|
||||
description:
|
||||
'Returns information about a given feed generator including TOS & offered feed URIs',
|
||||
output: {
|
||||
encoding: 'application/json',
|
||||
schema: {
|
||||
type: 'object',
|
||||
required: ['did', 'feeds'],
|
||||
properties: {
|
||||
did: {
|
||||
type: 'string',
|
||||
format: 'did',
|
||||
},
|
||||
feeds: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'ref',
|
||||
ref: 'lex:app.bsky.feed.describeFeedGenerator#feed',
|
||||
},
|
||||
},
|
||||
links: {
|
||||
type: 'ref',
|
||||
ref: 'lex:app.bsky.feed.describeFeedGenerator#links',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
feed: {
|
||||
type: 'object',
|
||||
required: ['uri'],
|
||||
properties: {
|
||||
uri: {
|
||||
type: 'string',
|
||||
format: 'at-uri',
|
||||
},
|
||||
},
|
||||
},
|
||||
links: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
privacyPolicy: {
|
||||
type: 'string',
|
||||
},
|
||||
termsOfService: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
AppBskyFeedGenerator: {
|
||||
lexicon: 1,
|
||||
id: 'app.bsky.feed.generator',
|
||||
@ -4446,50 +4590,6 @@ export const schemaDict = {
|
||||
},
|
||||
},
|
||||
},
|
||||
AppBskyFeedGetBookmarkedFeeds: {
|
||||
lexicon: 1,
|
||||
id: 'app.bsky.feed.getBookmarkedFeeds',
|
||||
defs: {
|
||||
main: {
|
||||
type: 'query',
|
||||
description:
|
||||
"Retrieve a list of the authenticated user's bookmarked feeds",
|
||||
parameters: {
|
||||
type: 'params',
|
||||
properties: {
|
||||
limit: {
|
||||
type: 'integer',
|
||||
minimum: 1,
|
||||
maximum: 100,
|
||||
default: 50,
|
||||
},
|
||||
cursor: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
output: {
|
||||
encoding: 'application/json',
|
||||
schema: {
|
||||
type: 'object',
|
||||
required: ['feeds'],
|
||||
properties: {
|
||||
cursor: {
|
||||
type: 'string',
|
||||
},
|
||||
feeds: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'ref',
|
||||
ref: 'lex:app.bsky.feed.defs#generatorView',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
AppBskyFeedGetFeed: {
|
||||
lexicon: 1,
|
||||
id: 'app.bsky.feed.getFeed',
|
||||
@ -4536,6 +4636,51 @@ export const schemaDict = {
|
||||
},
|
||||
},
|
||||
},
|
||||
errors: [
|
||||
{
|
||||
name: 'UnknownFeed',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
AppBskyFeedGetFeedGenerator: {
|
||||
lexicon: 1,
|
||||
id: 'app.bsky.feed.getFeedGenerator',
|
||||
defs: {
|
||||
main: {
|
||||
type: 'query',
|
||||
description:
|
||||
'Get information about a specific feed offered by a feed generator, such as its online status',
|
||||
parameters: {
|
||||
type: 'params',
|
||||
required: ['feed'],
|
||||
properties: {
|
||||
feed: {
|
||||
type: 'string',
|
||||
format: 'at-uri',
|
||||
},
|
||||
},
|
||||
},
|
||||
output: {
|
||||
encoding: 'application/json',
|
||||
schema: {
|
||||
type: 'object',
|
||||
required: ['view', 'isOnline', 'isValid'],
|
||||
properties: {
|
||||
view: {
|
||||
type: 'ref',
|
||||
ref: 'lex:app.bsky.feed.defs#generatorView',
|
||||
},
|
||||
isOnline: {
|
||||
type: 'boolean',
|
||||
},
|
||||
isValid: {
|
||||
type: 'boolean',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -4584,6 +4729,11 @@ export const schemaDict = {
|
||||
},
|
||||
},
|
||||
},
|
||||
errors: [
|
||||
{
|
||||
name: 'UnknownFeed',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -4807,6 +4957,49 @@ export const schemaDict = {
|
||||
},
|
||||
},
|
||||
},
|
||||
AppBskyFeedGetSavedFeeds: {
|
||||
lexicon: 1,
|
||||
id: 'app.bsky.feed.getSavedFeeds',
|
||||
defs: {
|
||||
main: {
|
||||
type: 'query',
|
||||
description: "Retrieve a list of the authenticated user's saved feeds",
|
||||
parameters: {
|
||||
type: 'params',
|
||||
properties: {
|
||||
limit: {
|
||||
type: 'integer',
|
||||
minimum: 1,
|
||||
maximum: 100,
|
||||
default: 50,
|
||||
},
|
||||
cursor: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
output: {
|
||||
encoding: 'application/json',
|
||||
schema: {
|
||||
type: 'object',
|
||||
required: ['feeds'],
|
||||
properties: {
|
||||
cursor: {
|
||||
type: 'string',
|
||||
},
|
||||
feeds: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'ref',
|
||||
ref: 'lex:app.bsky.feed.defs#generatorView',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
AppBskyFeedGetTimeline: {
|
||||
lexicon: 1,
|
||||
id: 'app.bsky.feed.getTimeline',
|
||||
@ -5002,13 +5195,36 @@ export const schemaDict = {
|
||||
},
|
||||
},
|
||||
},
|
||||
AppBskyFeedUnbookmarkFeed: {
|
||||
AppBskyFeedSaveFeed: {
|
||||
lexicon: 1,
|
||||
id: 'app.bsky.feed.unbookmarkFeed',
|
||||
id: 'app.bsky.feed.saveFeed',
|
||||
defs: {
|
||||
main: {
|
||||
type: 'procedure',
|
||||
description: 'Remove a bookmark for a 3rd party feed',
|
||||
description: 'Save a 3rd party feed for use across clients',
|
||||
input: {
|
||||
encoding: 'application/json',
|
||||
schema: {
|
||||
type: 'object',
|
||||
required: ['feed'],
|
||||
properties: {
|
||||
feed: {
|
||||
type: 'string',
|
||||
format: 'at-uri',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
AppBskyFeedUnsaveFeed: {
|
||||
lexicon: 1,
|
||||
id: 'app.bsky.feed.unsaveFeed',
|
||||
defs: {
|
||||
main: {
|
||||
type: 'procedure',
|
||||
description: 'Unsave a 3rd party feed',
|
||||
input: {
|
||||
encoding: 'application/json',
|
||||
schema: {
|
||||
@ -6029,33 +6245,37 @@ export const ids = {
|
||||
ComAtprotoSyncRequestCrawl: 'com.atproto.sync.requestCrawl',
|
||||
ComAtprotoSyncSubscribeRepos: 'com.atproto.sync.subscribeRepos',
|
||||
AppBskyActorDefs: 'app.bsky.actor.defs',
|
||||
AppBskyActorGetPreferences: 'app.bsky.actor.getPreferences',
|
||||
AppBskyActorGetProfile: 'app.bsky.actor.getProfile',
|
||||
AppBskyActorGetProfiles: 'app.bsky.actor.getProfiles',
|
||||
AppBskyActorGetSuggestions: 'app.bsky.actor.getSuggestions',
|
||||
AppBskyActorProfile: 'app.bsky.actor.profile',
|
||||
AppBskyActorPutPreferences: 'app.bsky.actor.putPreferences',
|
||||
AppBskyActorSearchActors: 'app.bsky.actor.searchActors',
|
||||
AppBskyActorSearchActorsTypeahead: 'app.bsky.actor.searchActorsTypeahead',
|
||||
AppBskyEmbedExternal: 'app.bsky.embed.external',
|
||||
AppBskyEmbedImages: 'app.bsky.embed.images',
|
||||
AppBskyEmbedRecord: 'app.bsky.embed.record',
|
||||
AppBskyEmbedRecordWithMedia: 'app.bsky.embed.recordWithMedia',
|
||||
AppBskyFeedBookmarkFeed: 'app.bsky.feed.bookmarkFeed',
|
||||
AppBskyFeedDefs: 'app.bsky.feed.defs',
|
||||
AppBskyFeedDescribeFeedGenerator: 'app.bsky.feed.describeFeedGenerator',
|
||||
AppBskyFeedGenerator: 'app.bsky.feed.generator',
|
||||
AppBskyFeedGetActorFeeds: 'app.bsky.feed.getActorFeeds',
|
||||
AppBskyFeedGetAuthorFeed: 'app.bsky.feed.getAuthorFeed',
|
||||
AppBskyFeedGetBookmarkedFeeds: 'app.bsky.feed.getBookmarkedFeeds',
|
||||
AppBskyFeedGetFeed: 'app.bsky.feed.getFeed',
|
||||
AppBskyFeedGetFeedGenerator: 'app.bsky.feed.getFeedGenerator',
|
||||
AppBskyFeedGetFeedSkeleton: 'app.bsky.feed.getFeedSkeleton',
|
||||
AppBskyFeedGetLikes: 'app.bsky.feed.getLikes',
|
||||
AppBskyFeedGetPostThread: 'app.bsky.feed.getPostThread',
|
||||
AppBskyFeedGetPosts: 'app.bsky.feed.getPosts',
|
||||
AppBskyFeedGetRepostedBy: 'app.bsky.feed.getRepostedBy',
|
||||
AppBskyFeedGetSavedFeeds: 'app.bsky.feed.getSavedFeeds',
|
||||
AppBskyFeedGetTimeline: 'app.bsky.feed.getTimeline',
|
||||
AppBskyFeedLike: 'app.bsky.feed.like',
|
||||
AppBskyFeedPost: 'app.bsky.feed.post',
|
||||
AppBskyFeedRepost: 'app.bsky.feed.repost',
|
||||
AppBskyFeedUnbookmarkFeed: 'app.bsky.feed.unbookmarkFeed',
|
||||
AppBskyFeedSaveFeed: 'app.bsky.feed.saveFeed',
|
||||
AppBskyFeedUnsaveFeed: 'app.bsky.feed.unsaveFeed',
|
||||
AppBskyGraphBlock: 'app.bsky.graph.block',
|
||||
AppBskyGraphDefs: 'app.bsky.graph.defs',
|
||||
AppBskyGraphFollow: 'app.bsky.graph.follow',
|
||||
|
@ -103,3 +103,44 @@ export function isViewerState(v: unknown): v is ViewerState {
|
||||
export function validateViewerState(v: unknown): ValidationResult {
|
||||
return lexicons.validate('app.bsky.actor.defs#viewerState', v)
|
||||
}
|
||||
|
||||
export type Preferences = (
|
||||
| AdultContentPref
|
||||
| ContentLabelPref
|
||||
| { $type: string; [k: string]: unknown }
|
||||
)[]
|
||||
|
||||
export interface AdultContentPref {
|
||||
enabled: boolean
|
||||
[k: string]: unknown
|
||||
}
|
||||
|
||||
export function isAdultContentPref(v: unknown): v is AdultContentPref {
|
||||
return (
|
||||
isObj(v) &&
|
||||
hasProp(v, '$type') &&
|
||||
v.$type === 'app.bsky.actor.defs#adultContentPref'
|
||||
)
|
||||
}
|
||||
|
||||
export function validateAdultContentPref(v: unknown): ValidationResult {
|
||||
return lexicons.validate('app.bsky.actor.defs#adultContentPref', v)
|
||||
}
|
||||
|
||||
export interface ContentLabelPref {
|
||||
label: string
|
||||
visibility: 'show' | 'warn' | 'hide' | (string & {})
|
||||
[k: string]: unknown
|
||||
}
|
||||
|
||||
export function isContentLabelPref(v: unknown): v is ContentLabelPref {
|
||||
return (
|
||||
isObj(v) &&
|
||||
hasProp(v, '$type') &&
|
||||
v.$type === 'app.bsky.actor.defs#contentLabelPref'
|
||||
)
|
||||
}
|
||||
|
||||
export function validateContentLabelPref(v: unknown): ValidationResult {
|
||||
return lexicons.validate('app.bsky.actor.defs#contentLabelPref', v)
|
||||
}
|
||||
|
40
src/lexicon/types/app/bsky/actor/getPreferences.ts
Normal file
40
src/lexicon/types/app/bsky/actor/getPreferences.ts
Normal file
@ -0,0 +1,40 @@
|
||||
/**
|
||||
* GENERATED CODE - DO NOT MODIFY
|
||||
*/
|
||||
import express from 'express'
|
||||
import { ValidationResult, BlobRef } from '@atproto/lexicon'
|
||||
import { lexicons } from '../../../../lexicons'
|
||||
import { isObj, hasProp } from '../../../../util'
|
||||
import { CID } from 'multiformats/cid'
|
||||
import { HandlerAuth } from '@atproto/xrpc-server'
|
||||
import * as AppBskyActorDefs from './defs'
|
||||
|
||||
export interface QueryParams {}
|
||||
|
||||
export type InputSchema = undefined
|
||||
|
||||
export interface OutputSchema {
|
||||
preferences: AppBskyActorDefs.Preferences
|
||||
[k: string]: unknown
|
||||
}
|
||||
|
||||
export type HandlerInput = undefined
|
||||
|
||||
export interface HandlerSuccess {
|
||||
encoding: 'application/json'
|
||||
body: OutputSchema
|
||||
}
|
||||
|
||||
export interface HandlerError {
|
||||
status: number
|
||||
message?: string
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
export type Handler<HA extends HandlerAuth = never> = (ctx: {
|
||||
auth: HA
|
||||
params: QueryParams
|
||||
input: HandlerInput
|
||||
req: express.Request
|
||||
res: express.Response
|
||||
}) => Promise<HandlerOutput> | HandlerOutput
|
36
src/lexicon/types/app/bsky/actor/putPreferences.ts
Normal file
36
src/lexicon/types/app/bsky/actor/putPreferences.ts
Normal file
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* GENERATED CODE - DO NOT MODIFY
|
||||
*/
|
||||
import express from 'express'
|
||||
import { ValidationResult, BlobRef } from '@atproto/lexicon'
|
||||
import { lexicons } from '../../../../lexicons'
|
||||
import { isObj, hasProp } from '../../../../util'
|
||||
import { CID } from 'multiformats/cid'
|
||||
import { HandlerAuth } from '@atproto/xrpc-server'
|
||||
import * as AppBskyActorDefs from './defs'
|
||||
|
||||
export interface QueryParams {}
|
||||
|
||||
export interface InputSchema {
|
||||
preferences: AppBskyActorDefs.Preferences
|
||||
[k: string]: unknown
|
||||
}
|
||||
|
||||
export interface HandlerInput {
|
||||
encoding: 'application/json'
|
||||
body: InputSchema
|
||||
}
|
||||
|
||||
export interface HandlerError {
|
||||
status: number
|
||||
message?: string
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | void
|
||||
export type Handler<HA extends HandlerAuth = never> = (ctx: {
|
||||
auth: HA
|
||||
params: QueryParams
|
||||
input: HandlerInput
|
||||
req: express.Request
|
||||
res: express.Response
|
||||
}) => Promise<HandlerOutput> | HandlerOutput
|
@ -6,6 +6,7 @@ import { lexicons } from '../../../../lexicons'
|
||||
import { isObj, hasProp } from '../../../../util'
|
||||
import { CID } from 'multiformats/cid'
|
||||
import * as ComAtprotoRepoStrongRef from '../../../com/atproto/repo/strongRef'
|
||||
import * as AppBskyFeedDefs from '../feed/defs'
|
||||
import * as AppBskyActorDefs from '../actor/defs'
|
||||
import * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs'
|
||||
import * as AppBskyEmbedImages from './images'
|
||||
@ -35,6 +36,7 @@ export interface View {
|
||||
| ViewRecord
|
||||
| ViewNotFound
|
||||
| ViewBlocked
|
||||
| AppBskyFeedDefs.GeneratorView
|
||||
| { $type: string; [k: string]: unknown }
|
||||
[k: string]: unknown
|
||||
}
|
||||
|
@ -188,12 +188,14 @@ export function validateBlockedPost(v: unknown): ValidationResult {
|
||||
|
||||
export interface GeneratorView {
|
||||
uri: string
|
||||
cid: string
|
||||
did?: string
|
||||
creator: AppBskyActorDefs.ProfileView
|
||||
displayName?: string
|
||||
description?: string
|
||||
descriptionFacets?: AppBskyRichtextFacet.Main[]
|
||||
avatar?: string
|
||||
likeCount?: number
|
||||
viewer?: GeneratorViewerState
|
||||
indexedAt: string
|
||||
[k: string]: unknown
|
||||
@ -212,7 +214,7 @@ export function validateGeneratorView(v: unknown): ValidationResult {
|
||||
}
|
||||
|
||||
export interface GeneratorViewerState {
|
||||
subscribed?: boolean
|
||||
saved?: boolean
|
||||
like?: string
|
||||
[k: string]: unknown
|
||||
}
|
||||
|
76
src/lexicon/types/app/bsky/feed/describeFeedGenerator.ts
Normal file
76
src/lexicon/types/app/bsky/feed/describeFeedGenerator.ts
Normal file
@ -0,0 +1,76 @@
|
||||
/**
|
||||
* GENERATED CODE - DO NOT MODIFY
|
||||
*/
|
||||
import express from 'express'
|
||||
import { ValidationResult, BlobRef } from '@atproto/lexicon'
|
||||
import { lexicons } from '../../../../lexicons'
|
||||
import { isObj, hasProp } from '../../../../util'
|
||||
import { CID } from 'multiformats/cid'
|
||||
import { HandlerAuth } from '@atproto/xrpc-server'
|
||||
|
||||
export interface QueryParams {}
|
||||
|
||||
export type InputSchema = undefined
|
||||
|
||||
export interface OutputSchema {
|
||||
did: string
|
||||
feeds: Feed[]
|
||||
links?: Links
|
||||
[k: string]: unknown
|
||||
}
|
||||
|
||||
export type HandlerInput = undefined
|
||||
|
||||
export interface HandlerSuccess {
|
||||
encoding: 'application/json'
|
||||
body: OutputSchema
|
||||
}
|
||||
|
||||
export interface HandlerError {
|
||||
status: number
|
||||
message?: string
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
export type Handler<HA extends HandlerAuth = never> = (ctx: {
|
||||
auth: HA
|
||||
params: QueryParams
|
||||
input: HandlerInput
|
||||
req: express.Request
|
||||
res: express.Response
|
||||
}) => Promise<HandlerOutput> | HandlerOutput
|
||||
|
||||
export interface Feed {
|
||||
uri: string
|
||||
[k: string]: unknown
|
||||
}
|
||||
|
||||
export function isFeed(v: unknown): v is Feed {
|
||||
return (
|
||||
isObj(v) &&
|
||||
hasProp(v, '$type') &&
|
||||
v.$type === 'app.bsky.feed.describeFeedGenerator#feed'
|
||||
)
|
||||
}
|
||||
|
||||
export function validateFeed(v: unknown): ValidationResult {
|
||||
return lexicons.validate('app.bsky.feed.describeFeedGenerator#feed', v)
|
||||
}
|
||||
|
||||
export interface Links {
|
||||
privacyPolicy?: string
|
||||
termsOfService?: string
|
||||
[k: string]: unknown
|
||||
}
|
||||
|
||||
export function isLinks(v: unknown): v is Links {
|
||||
return (
|
||||
isObj(v) &&
|
||||
hasProp(v, '$type') &&
|
||||
v.$type === 'app.bsky.feed.describeFeedGenerator#links'
|
||||
)
|
||||
}
|
||||
|
||||
export function validateLinks(v: unknown): ValidationResult {
|
||||
return lexicons.validate('app.bsky.feed.describeFeedGenerator#links', v)
|
||||
}
|
@ -33,6 +33,7 @@ export interface HandlerSuccess {
|
||||
export interface HandlerError {
|
||||
status: number
|
||||
message?: string
|
||||
error?: 'UnknownFeed'
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
|
44
src/lexicon/types/app/bsky/feed/getFeedGenerator.ts
Normal file
44
src/lexicon/types/app/bsky/feed/getFeedGenerator.ts
Normal file
@ -0,0 +1,44 @@
|
||||
/**
|
||||
* GENERATED CODE - DO NOT MODIFY
|
||||
*/
|
||||
import express from 'express'
|
||||
import { ValidationResult, BlobRef } from '@atproto/lexicon'
|
||||
import { lexicons } from '../../../../lexicons'
|
||||
import { isObj, hasProp } from '../../../../util'
|
||||
import { CID } from 'multiformats/cid'
|
||||
import { HandlerAuth } from '@atproto/xrpc-server'
|
||||
import * as AppBskyFeedDefs from './defs'
|
||||
|
||||
export interface QueryParams {
|
||||
feed: string
|
||||
}
|
||||
|
||||
export type InputSchema = undefined
|
||||
|
||||
export interface OutputSchema {
|
||||
view: AppBskyFeedDefs.GeneratorView
|
||||
isOnline: boolean
|
||||
isValid: boolean
|
||||
[k: string]: unknown
|
||||
}
|
||||
|
||||
export type HandlerInput = undefined
|
||||
|
||||
export interface HandlerSuccess {
|
||||
encoding: 'application/json'
|
||||
body: OutputSchema
|
||||
}
|
||||
|
||||
export interface HandlerError {
|
||||
status: number
|
||||
message?: string
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
export type Handler<HA extends HandlerAuth = never> = (ctx: {
|
||||
auth: HA
|
||||
params: QueryParams
|
||||
input: HandlerInput
|
||||
req: express.Request
|
||||
res: express.Response
|
||||
}) => Promise<HandlerOutput> | HandlerOutput
|
@ -33,6 +33,7 @@ export interface HandlerSuccess {
|
||||
export interface HandlerError {
|
||||
status: number
|
||||
message?: string
|
||||
error?: 'UnknownFeed'
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
|
@ -12,6 +12,12 @@ import * as ComAtprotoAdminDefs from './defs'
|
||||
export interface QueryParams {
|
||||
subject?: string
|
||||
resolved?: boolean
|
||||
actionType?:
|
||||
| 'com.atproto.admin.defs#takedown'
|
||||
| 'com.atproto.admin.defs#flag'
|
||||
| 'com.atproto.admin.defs#acknowledge'
|
||||
| 'com.atproto.admin.defs#escalate'
|
||||
| (string & {})
|
||||
limit: number
|
||||
cursor?: string
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ export interface QueryParams {}
|
||||
export interface InputSchema {
|
||||
email: string
|
||||
handle: string
|
||||
did?: string
|
||||
inviteCode?: string
|
||||
password: string
|
||||
recoveryKey?: string
|
||||
@ -46,6 +47,8 @@ export interface HandlerError {
|
||||
| 'InvalidInviteCode'
|
||||
| 'HandleNotAvailable'
|
||||
| 'UnsupportedDomain'
|
||||
| 'UnresolvableDid'
|
||||
| 'IncompatibleDidDoc'
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
|
16
src/methods/describe-generator.ts
Normal file
16
src/methods/describe-generator.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { Server } from '../lexicon'
|
||||
import { AppContext } from '../config'
|
||||
import algos from '../algos'
|
||||
|
||||
export default function (server: Server, ctx: AppContext) {
|
||||
server.app.bsky.feed.describeFeedGenerator(async () => {
|
||||
const feeds = Object.keys(algos).map((uri) => ({ uri }))
|
||||
return {
|
||||
encoding: 'application/json',
|
||||
body: {
|
||||
did: ctx.cfg.serviceDid,
|
||||
feeds,
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
32
src/methods/feed-generation.ts
Normal file
32
src/methods/feed-generation.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import { InvalidRequestError } from '@atproto/xrpc-server'
|
||||
import { Server } from '../lexicon'
|
||||
import { AppContext } from '../config'
|
||||
import algos from '../algos'
|
||||
import { validateAuth } from '../auth'
|
||||
|
||||
export default function (server: Server, ctx: AppContext) {
|
||||
server.app.bsky.feed.getFeedSkeleton(async ({ params, req }) => {
|
||||
const algo = algos[params.feed]
|
||||
if (!algo) {
|
||||
throw new InvalidRequestError(
|
||||
'Unsupported algorithm',
|
||||
'UnsupportedAlgorithm',
|
||||
)
|
||||
}
|
||||
/**
|
||||
* Example of how to check auth if giving user-specific results:
|
||||
*
|
||||
* const requesterDid = await validateAuth(
|
||||
* req,
|
||||
* ctx.cfg.serviceDid,
|
||||
* ctx.didResolver,
|
||||
* )
|
||||
*/
|
||||
|
||||
const body = await algo(ctx, params)
|
||||
return {
|
||||
encoding: 'application/json',
|
||||
body: body,
|
||||
}
|
||||
})
|
||||
}
|
@ -3,7 +3,8 @@ import events from 'events'
|
||||
import express from 'express'
|
||||
import { DidResolver, MemoryCache } from '@atproto/did-resolver'
|
||||
import { createServer } from './lexicon'
|
||||
import feedGeneration from './feed-generation'
|
||||
import feedGeneration from './methods/feed-generation'
|
||||
import describeGenerator from './methods/describe-generator'
|
||||
import { createDb, Database, migrateToLatest } from './db'
|
||||
import { FirehoseSubscription } from './subscription'
|
||||
import { AppContext, Config } from './config'
|
||||
@ -60,6 +61,7 @@ export class FeedGenerator {
|
||||
cfg,
|
||||
}
|
||||
feedGeneration(server, ctx)
|
||||
describeGenerator(server, ctx)
|
||||
app.use(server.xrpc.router)
|
||||
app.use(wellKnown(cfg.hostname))
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user