diff --git a/lexicons/app/bsky/unspecced/getTaggedSuggestions.json b/lexicons/app/bsky/unspecced/getTaggedSuggestions.json new file mode 100644 index 00000000000..9fd98ffefb0 --- /dev/null +++ b/lexicons/app/bsky/unspecced/getTaggedSuggestions.json @@ -0,0 +1,42 @@ +{ + "lexicon": 1, + "id": "app.bsky.unspecced.getTaggedSuggestions", + "defs": { + "main": { + "type": "query", + "description": "Get a list of suggestions (feeds and users) tagged with categories", + "parameters": { + "type": "params", + "properties": {} + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["suggestions"], + "properties": { + "suggestions": { + "type": "array", + "items": { + "type": "ref", + "ref": "#suggestion" + } + } + } + } + } + }, + "suggestion": { + "type": "object", + "required": ["tag", "subjectType", "subject"], + "properties": { + "tag": { "type": "string" }, + "subjectType": { + "type": "string", + "knownValues": ["actor", "feed"] + }, + "subject": { "type": "string", "format": "uri" } + } + } + } +} diff --git a/packages/api/src/client/index.ts b/packages/api/src/client/index.ts index c996a63b4ea..2ff30e38151 100644 --- a/packages/api/src/client/index.ts +++ b/packages/api/src/client/index.ts @@ -147,6 +147,7 @@ import * as AppBskyRichtextFacet from './types/app/bsky/richtext/facet' import * as AppBskyUnspeccedDefs from './types/app/bsky/unspecced/defs' import * as AppBskyUnspeccedGetPopular from './types/app/bsky/unspecced/getPopular' import * as AppBskyUnspeccedGetPopularFeedGenerators from './types/app/bsky/unspecced/getPopularFeedGenerators' +import * as AppBskyUnspeccedGetTaggedSuggestions from './types/app/bsky/unspecced/getTaggedSuggestions' import * as AppBskyUnspeccedGetTimelineSkeleton from './types/app/bsky/unspecced/getTimelineSkeleton' import * as AppBskyUnspeccedSearchActorsSkeleton from './types/app/bsky/unspecced/searchActorsSkeleton' import * as AppBskyUnspeccedSearchPostsSkeleton from './types/app/bsky/unspecced/searchPostsSkeleton' @@ -291,6 +292,7 @@ export * as AppBskyRichtextFacet from './types/app/bsky/richtext/facet' export * as AppBskyUnspeccedDefs from './types/app/bsky/unspecced/defs' export * as AppBskyUnspeccedGetPopular from './types/app/bsky/unspecced/getPopular' export * as AppBskyUnspeccedGetPopularFeedGenerators from './types/app/bsky/unspecced/getPopularFeedGenerators' +export * as AppBskyUnspeccedGetTaggedSuggestions from './types/app/bsky/unspecced/getTaggedSuggestions' export * as AppBskyUnspeccedGetTimelineSkeleton from './types/app/bsky/unspecced/getTimelineSkeleton' export * as AppBskyUnspeccedSearchActorsSkeleton from './types/app/bsky/unspecced/searchActorsSkeleton' export * as AppBskyUnspeccedSearchPostsSkeleton from './types/app/bsky/unspecced/searchPostsSkeleton' @@ -2508,6 +2510,17 @@ export class UnspeccedNS { }) } + getTaggedSuggestions( + params?: AppBskyUnspeccedGetTaggedSuggestions.QueryParams, + opts?: AppBskyUnspeccedGetTaggedSuggestions.CallOptions, + ): Promise { + return this._service.xrpc + .call('app.bsky.unspecced.getTaggedSuggestions', params, undefined, opts) + .catch((e) => { + throw AppBskyUnspeccedGetTaggedSuggestions.toKnownErr(e) + }) + } + getTimelineSkeleton( params?: AppBskyUnspeccedGetTimelineSkeleton.QueryParams, opts?: AppBskyUnspeccedGetTimelineSkeleton.CallOptions, diff --git a/packages/api/src/client/lexicons.ts b/packages/api/src/client/lexicons.ts index 09a586338ea..86aaa2e8e19 100644 --- a/packages/api/src/client/lexicons.ts +++ b/packages/api/src/client/lexicons.ts @@ -7924,6 +7924,54 @@ export const schemaDict = { }, }, }, + AppBskyUnspeccedGetTaggedSuggestions: { + lexicon: 1, + id: 'app.bsky.unspecced.getTaggedSuggestions', + defs: { + main: { + type: 'query', + description: + 'Get a list of suggestions (feeds and users) tagged with categories', + parameters: { + type: 'params', + properties: {}, + }, + output: { + encoding: 'application/json', + schema: { + type: 'object', + required: ['suggestions'], + properties: { + suggestions: { + type: 'array', + items: { + type: 'ref', + ref: 'lex:app.bsky.unspecced.getTaggedSuggestions#suggestion', + }, + }, + }, + }, + }, + }, + suggestion: { + type: 'object', + required: ['tag', 'subjectType', 'subject'], + properties: { + tag: { + type: 'string', + }, + subjectType: { + type: 'string', + knownValues: ['actor', 'feed'], + }, + subject: { + type: 'string', + format: 'uri', + }, + }, + }, + }, + }, AppBskyUnspeccedGetTimelineSkeleton: { lexicon: 1, id: 'app.bsky.unspecced.getTimelineSkeleton', @@ -8257,6 +8305,8 @@ export const ids = { AppBskyUnspeccedGetPopular: 'app.bsky.unspecced.getPopular', AppBskyUnspeccedGetPopularFeedGenerators: 'app.bsky.unspecced.getPopularFeedGenerators', + AppBskyUnspeccedGetTaggedSuggestions: + 'app.bsky.unspecced.getTaggedSuggestions', AppBskyUnspeccedGetTimelineSkeleton: 'app.bsky.unspecced.getTimelineSkeleton', AppBskyUnspeccedSearchActorsSkeleton: 'app.bsky.unspecced.searchActorsSkeleton', diff --git a/packages/api/src/client/types/app/bsky/unspecced/getTaggedSuggestions.ts b/packages/api/src/client/types/app/bsky/unspecced/getTaggedSuggestions.ts new file mode 100644 index 00000000000..a35e2411756 --- /dev/null +++ b/packages/api/src/client/types/app/bsky/unspecced/getTaggedSuggestions.ts @@ -0,0 +1,55 @@ +/** + * GENERATED CODE - DO NOT MODIFY + */ +import { Headers, XRPCError } from '@atproto/xrpc' +import { ValidationResult, BlobRef } from '@atproto/lexicon' +import { isObj, hasProp } from '../../../../util' +import { lexicons } from '../../../../lexicons' +import { CID } from 'multiformats/cid' + +export interface QueryParams {} + +export type InputSchema = undefined + +export interface OutputSchema { + suggestions: Suggestion[] + [k: string]: unknown +} + +export interface CallOptions { + headers?: Headers +} + +export interface Response { + success: boolean + headers: Headers + data: OutputSchema +} + +export function toKnownErr(e: any) { + if (e instanceof XRPCError) { + } + return e +} + +export interface Suggestion { + tag: string + subjectType: 'actor' | 'feed' | (string & {}) + subject: string + [k: string]: unknown +} + +export function isSuggestion(v: unknown): v is Suggestion { + return ( + isObj(v) && + hasProp(v, '$type') && + v.$type === 'app.bsky.unspecced.getTaggedSuggestions#suggestion' + ) +} + +export function validateSuggestion(v: unknown): ValidationResult { + return lexicons.validate( + 'app.bsky.unspecced.getTaggedSuggestions#suggestion', + v, + ) +} diff --git a/packages/bsky/src/lexicon/index.ts b/packages/bsky/src/lexicon/index.ts index 917078e5bb0..4efd7f7837a 100644 --- a/packages/bsky/src/lexicon/index.ts +++ b/packages/bsky/src/lexicon/index.ts @@ -124,6 +124,7 @@ import * as AppBskyNotificationRegisterPush from './types/app/bsky/notification/ import * as AppBskyNotificationUpdateSeen from './types/app/bsky/notification/updateSeen' import * as AppBskyUnspeccedGetPopular from './types/app/bsky/unspecced/getPopular' import * as AppBskyUnspeccedGetPopularFeedGenerators from './types/app/bsky/unspecced/getPopularFeedGenerators' +import * as AppBskyUnspeccedGetTaggedSuggestions from './types/app/bsky/unspecced/getTaggedSuggestions' import * as AppBskyUnspeccedGetTimelineSkeleton from './types/app/bsky/unspecced/getTimelineSkeleton' import * as AppBskyUnspeccedSearchActorsSkeleton from './types/app/bsky/unspecced/searchActorsSkeleton' import * as AppBskyUnspeccedSearchPostsSkeleton from './types/app/bsky/unspecced/searchPostsSkeleton' @@ -1613,6 +1614,17 @@ export class UnspeccedNS { return this._server.xrpc.method(nsid, cfg) } + getTaggedSuggestions( + cfg: ConfigOf< + AV, + AppBskyUnspeccedGetTaggedSuggestions.Handler>, + AppBskyUnspeccedGetTaggedSuggestions.HandlerReqCtx> + >, + ) { + const nsid = 'app.bsky.unspecced.getTaggedSuggestions' // @ts-ignore + return this._server.xrpc.method(nsid, cfg) + } + getTimelineSkeleton( cfg: ConfigOf< AV, @@ -1658,13 +1670,11 @@ type RouteRateLimitOpts = { calcKey?: (ctx: T) => string calcPoints?: (ctx: T) => number } -type HandlerOpts = { blobLimit?: number } type HandlerRateLimitOpts = SharedRateLimitOpts | RouteRateLimitOpts type ConfigOf = | Handler | { auth?: Auth - opts?: HandlerOpts rateLimit?: HandlerRateLimitOpts | HandlerRateLimitOpts[] handler: Handler } diff --git a/packages/bsky/src/lexicon/lexicons.ts b/packages/bsky/src/lexicon/lexicons.ts index 09a586338ea..86aaa2e8e19 100644 --- a/packages/bsky/src/lexicon/lexicons.ts +++ b/packages/bsky/src/lexicon/lexicons.ts @@ -7924,6 +7924,54 @@ export const schemaDict = { }, }, }, + AppBskyUnspeccedGetTaggedSuggestions: { + lexicon: 1, + id: 'app.bsky.unspecced.getTaggedSuggestions', + defs: { + main: { + type: 'query', + description: + 'Get a list of suggestions (feeds and users) tagged with categories', + parameters: { + type: 'params', + properties: {}, + }, + output: { + encoding: 'application/json', + schema: { + type: 'object', + required: ['suggestions'], + properties: { + suggestions: { + type: 'array', + items: { + type: 'ref', + ref: 'lex:app.bsky.unspecced.getTaggedSuggestions#suggestion', + }, + }, + }, + }, + }, + }, + suggestion: { + type: 'object', + required: ['tag', 'subjectType', 'subject'], + properties: { + tag: { + type: 'string', + }, + subjectType: { + type: 'string', + knownValues: ['actor', 'feed'], + }, + subject: { + type: 'string', + format: 'uri', + }, + }, + }, + }, + }, AppBskyUnspeccedGetTimelineSkeleton: { lexicon: 1, id: 'app.bsky.unspecced.getTimelineSkeleton', @@ -8257,6 +8305,8 @@ export const ids = { AppBskyUnspeccedGetPopular: 'app.bsky.unspecced.getPopular', AppBskyUnspeccedGetPopularFeedGenerators: 'app.bsky.unspecced.getPopularFeedGenerators', + AppBskyUnspeccedGetTaggedSuggestions: + 'app.bsky.unspecced.getTaggedSuggestions', AppBskyUnspeccedGetTimelineSkeleton: 'app.bsky.unspecced.getTimelineSkeleton', AppBskyUnspeccedSearchActorsSkeleton: 'app.bsky.unspecced.searchActorsSkeleton', diff --git a/packages/bsky/src/lexicon/types/app/bsky/unspecced/getTaggedSuggestions.ts b/packages/bsky/src/lexicon/types/app/bsky/unspecced/getTaggedSuggestions.ts new file mode 100644 index 00000000000..e6319c54b4e --- /dev/null +++ b/packages/bsky/src/lexicon/types/app/bsky/unspecced/getTaggedSuggestions.ts @@ -0,0 +1,65 @@ +/** + * 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 { + suggestions: Suggestion[] + [k: string]: unknown +} + +export type HandlerInput = undefined + +export interface HandlerSuccess { + encoding: 'application/json' + body: OutputSchema + headers?: { [key: string]: string } +} + +export interface HandlerError { + status: number + message?: string +} + +export type HandlerOutput = HandlerError | HandlerSuccess +export type HandlerReqCtx = { + auth: HA + params: QueryParams + input: HandlerInput + req: express.Request + res: express.Response +} +export type Handler = ( + ctx: HandlerReqCtx, +) => Promise | HandlerOutput + +export interface Suggestion { + tag: string + subjectType: 'actor' | 'feed' | (string & {}) + subject: string + [k: string]: unknown +} + +export function isSuggestion(v: unknown): v is Suggestion { + return ( + isObj(v) && + hasProp(v, '$type') && + v.$type === 'app.bsky.unspecced.getTaggedSuggestions#suggestion' + ) +} + +export function validateSuggestion(v: unknown): ValidationResult { + return lexicons.validate( + 'app.bsky.unspecced.getTaggedSuggestions#suggestion', + v, + ) +} diff --git a/packages/pds/src/api/app/bsky/unspecced/getTaggedSuggestions.ts b/packages/pds/src/api/app/bsky/unspecced/getTaggedSuggestions.ts new file mode 100644 index 00000000000..ff4050bbc5c --- /dev/null +++ b/packages/pds/src/api/app/bsky/unspecced/getTaggedSuggestions.ts @@ -0,0 +1,44 @@ +import { Server } from '../../../../lexicon' +import AppContext from '../../../../context' +import { + authPassthru, + proxy, + proxyAppView, + resultPassthru, +} from '../../../proxy' + +// THIS IS A TEMPORARY UNSPECCED ROUTE +export default function (server: Server, ctx: AppContext) { + server.app.bsky.unspecced.getTaggedSuggestions({ + auth: ctx.authVerifier.access, + handler: async ({ auth, params, req }) => { + const proxied = await proxy( + ctx, + auth.credentials.audience, + async (agent) => { + const result = + await agent.api.app.bsky.unspecced.getTaggedSuggestions( + params, + authPassthru(req), + ) + return resultPassthru(result) + }, + ) + if (proxied !== null) { + return proxied + } + + const requester = auth.credentials.did + const res = await proxyAppView(ctx, async (agent) => + agent.api.app.bsky.unspecced.getTaggedSuggestions( + params, + await ctx.appviewAuthHeaders(requester), + ), + ) + return { + encoding: 'application/json', + body: res.data, + } + }, + }) +} diff --git a/packages/pds/src/api/app/bsky/unspecced/index.ts b/packages/pds/src/api/app/bsky/unspecced/index.ts index 6951400863d..7f404c76d48 100644 --- a/packages/pds/src/api/app/bsky/unspecced/index.ts +++ b/packages/pds/src/api/app/bsky/unspecced/index.ts @@ -2,9 +2,11 @@ import { Server } from '../../../../lexicon' import AppContext from '../../../../context' import getPopular from './getPopular' import getPopularFeedGenerators from './getPopularFeedGenerators' +import getTaggedSuggestions from './getTaggedSuggestions' // THIS IS A TEMPORARY UNSPECCED ROUTE export default function (server: Server, ctx: AppContext) { getPopular(server, ctx) getPopularFeedGenerators(server, ctx) + getTaggedSuggestions(server, ctx) } diff --git a/packages/pds/src/lexicon/index.ts b/packages/pds/src/lexicon/index.ts index 917078e5bb0..4efd7f7837a 100644 --- a/packages/pds/src/lexicon/index.ts +++ b/packages/pds/src/lexicon/index.ts @@ -124,6 +124,7 @@ import * as AppBskyNotificationRegisterPush from './types/app/bsky/notification/ import * as AppBskyNotificationUpdateSeen from './types/app/bsky/notification/updateSeen' import * as AppBskyUnspeccedGetPopular from './types/app/bsky/unspecced/getPopular' import * as AppBskyUnspeccedGetPopularFeedGenerators from './types/app/bsky/unspecced/getPopularFeedGenerators' +import * as AppBskyUnspeccedGetTaggedSuggestions from './types/app/bsky/unspecced/getTaggedSuggestions' import * as AppBskyUnspeccedGetTimelineSkeleton from './types/app/bsky/unspecced/getTimelineSkeleton' import * as AppBskyUnspeccedSearchActorsSkeleton from './types/app/bsky/unspecced/searchActorsSkeleton' import * as AppBskyUnspeccedSearchPostsSkeleton from './types/app/bsky/unspecced/searchPostsSkeleton' @@ -1613,6 +1614,17 @@ export class UnspeccedNS { return this._server.xrpc.method(nsid, cfg) } + getTaggedSuggestions( + cfg: ConfigOf< + AV, + AppBskyUnspeccedGetTaggedSuggestions.Handler>, + AppBskyUnspeccedGetTaggedSuggestions.HandlerReqCtx> + >, + ) { + const nsid = 'app.bsky.unspecced.getTaggedSuggestions' // @ts-ignore + return this._server.xrpc.method(nsid, cfg) + } + getTimelineSkeleton( cfg: ConfigOf< AV, @@ -1658,13 +1670,11 @@ type RouteRateLimitOpts = { calcKey?: (ctx: T) => string calcPoints?: (ctx: T) => number } -type HandlerOpts = { blobLimit?: number } type HandlerRateLimitOpts = SharedRateLimitOpts | RouteRateLimitOpts type ConfigOf = | Handler | { auth?: Auth - opts?: HandlerOpts rateLimit?: HandlerRateLimitOpts | HandlerRateLimitOpts[] handler: Handler } diff --git a/packages/pds/src/lexicon/lexicons.ts b/packages/pds/src/lexicon/lexicons.ts index 09a586338ea..86aaa2e8e19 100644 --- a/packages/pds/src/lexicon/lexicons.ts +++ b/packages/pds/src/lexicon/lexicons.ts @@ -7924,6 +7924,54 @@ export const schemaDict = { }, }, }, + AppBskyUnspeccedGetTaggedSuggestions: { + lexicon: 1, + id: 'app.bsky.unspecced.getTaggedSuggestions', + defs: { + main: { + type: 'query', + description: + 'Get a list of suggestions (feeds and users) tagged with categories', + parameters: { + type: 'params', + properties: {}, + }, + output: { + encoding: 'application/json', + schema: { + type: 'object', + required: ['suggestions'], + properties: { + suggestions: { + type: 'array', + items: { + type: 'ref', + ref: 'lex:app.bsky.unspecced.getTaggedSuggestions#suggestion', + }, + }, + }, + }, + }, + }, + suggestion: { + type: 'object', + required: ['tag', 'subjectType', 'subject'], + properties: { + tag: { + type: 'string', + }, + subjectType: { + type: 'string', + knownValues: ['actor', 'feed'], + }, + subject: { + type: 'string', + format: 'uri', + }, + }, + }, + }, + }, AppBskyUnspeccedGetTimelineSkeleton: { lexicon: 1, id: 'app.bsky.unspecced.getTimelineSkeleton', @@ -8257,6 +8305,8 @@ export const ids = { AppBskyUnspeccedGetPopular: 'app.bsky.unspecced.getPopular', AppBskyUnspeccedGetPopularFeedGenerators: 'app.bsky.unspecced.getPopularFeedGenerators', + AppBskyUnspeccedGetTaggedSuggestions: + 'app.bsky.unspecced.getTaggedSuggestions', AppBskyUnspeccedGetTimelineSkeleton: 'app.bsky.unspecced.getTimelineSkeleton', AppBskyUnspeccedSearchActorsSkeleton: 'app.bsky.unspecced.searchActorsSkeleton', diff --git a/packages/pds/src/lexicon/types/app/bsky/unspecced/getTaggedSuggestions.ts b/packages/pds/src/lexicon/types/app/bsky/unspecced/getTaggedSuggestions.ts new file mode 100644 index 00000000000..e6319c54b4e --- /dev/null +++ b/packages/pds/src/lexicon/types/app/bsky/unspecced/getTaggedSuggestions.ts @@ -0,0 +1,65 @@ +/** + * 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 { + suggestions: Suggestion[] + [k: string]: unknown +} + +export type HandlerInput = undefined + +export interface HandlerSuccess { + encoding: 'application/json' + body: OutputSchema + headers?: { [key: string]: string } +} + +export interface HandlerError { + status: number + message?: string +} + +export type HandlerOutput = HandlerError | HandlerSuccess +export type HandlerReqCtx = { + auth: HA + params: QueryParams + input: HandlerInput + req: express.Request + res: express.Response +} +export type Handler = ( + ctx: HandlerReqCtx, +) => Promise | HandlerOutput + +export interface Suggestion { + tag: string + subjectType: 'actor' | 'feed' | (string & {}) + subject: string + [k: string]: unknown +} + +export function isSuggestion(v: unknown): v is Suggestion { + return ( + isObj(v) && + hasProp(v, '$type') && + v.$type === 'app.bsky.unspecced.getTaggedSuggestions#suggestion' + ) +} + +export function validateSuggestion(v: unknown): ValidationResult { + return lexicons.validate( + 'app.bsky.unspecced.getTaggedSuggestions#suggestion', + v, + ) +}