diff --git a/lexicons/app/bsky/graph/getRelationships.json b/lexicons/app/bsky/graph/getRelationships.json index 5d28b3726fc..ccd495dea7d 100644 --- a/lexicons/app/bsky/graph/getRelationships.json +++ b/lexicons/app/bsky/graph/getRelationships.json @@ -32,7 +32,7 @@ "items": { "type": "union", "refs": [ - "app.bsky.graph.def#relationship", + "app.bsky.graph.defs#relationship", "app.bsky.graph.defs#notFoundActor" ] } diff --git a/packages/api/src/client/index.ts b/packages/api/src/client/index.ts index 228d589e8d5..c6463e93534 100644 --- a/packages/api/src/client/index.ts +++ b/packages/api/src/client/index.ts @@ -132,6 +132,7 @@ import * as AppBskyGraphGetListBlocks from './types/app/bsky/graph/getListBlocks import * as AppBskyGraphGetListMutes from './types/app/bsky/graph/getListMutes' import * as AppBskyGraphGetLists from './types/app/bsky/graph/getLists' import * as AppBskyGraphGetMutes from './types/app/bsky/graph/getMutes' +import * as AppBskyGraphGetRelationships from './types/app/bsky/graph/getRelationships' import * as AppBskyGraphGetSuggestedFollowsByActor from './types/app/bsky/graph/getSuggestedFollowsByActor' import * as AppBskyGraphList from './types/app/bsky/graph/list' import * as AppBskyGraphListblock from './types/app/bsky/graph/listblock' @@ -277,6 +278,7 @@ export * as AppBskyGraphGetListBlocks from './types/app/bsky/graph/getListBlocks export * as AppBskyGraphGetListMutes from './types/app/bsky/graph/getListMutes' export * as AppBskyGraphGetLists from './types/app/bsky/graph/getLists' export * as AppBskyGraphGetMutes from './types/app/bsky/graph/getMutes' +export * as AppBskyGraphGetRelationships from './types/app/bsky/graph/getRelationships' export * as AppBskyGraphGetSuggestedFollowsByActor from './types/app/bsky/graph/getSuggestedFollowsByActor' export * as AppBskyGraphList from './types/app/bsky/graph/list' export * as AppBskyGraphListblock from './types/app/bsky/graph/listblock' @@ -2057,6 +2059,17 @@ export class AppBskyGraphNS { }) } + getRelationships( + params?: AppBskyGraphGetRelationships.QueryParams, + opts?: AppBskyGraphGetRelationships.CallOptions, + ): Promise { + return this._service.xrpc + .call('app.bsky.graph.getRelationships', params, undefined, opts) + .catch((e) => { + throw AppBskyGraphGetRelationships.toKnownErr(e) + }) + } + getSuggestedFollowsByActor( params?: AppBskyGraphGetSuggestedFollowsByActor.QueryParams, opts?: AppBskyGraphGetSuggestedFollowsByActor.CallOptions, diff --git a/packages/api/src/client/lexicons.ts b/packages/api/src/client/lexicons.ts index 0c757a80b0f..fea624e9a04 100644 --- a/packages/api/src/client/lexicons.ts +++ b/packages/api/src/client/lexicons.ts @@ -6925,6 +6925,45 @@ export const schemaDict = { }, }, }, + notFoundActor: { + type: 'object', + description: 'indicates that a handle or DID could not be resolved', + required: ['actor', 'notFound'], + properties: { + actor: { + type: 'string', + format: 'at-identifier', + }, + notFound: { + type: 'boolean', + const: true, + }, + }, + }, + relationship: { + type: 'object', + description: + 'lists the bi-directional graph relationships between one actor (not indicated in the object), and the target actors (the DID included in the object)', + required: ['did'], + properties: { + did: { + type: 'string', + format: 'did', + }, + following: { + type: 'string', + format: 'at-uri', + description: + 'if the actor follows this DID, this is the AT-URI of the follow record', + }, + followedBy: { + type: 'string', + format: 'at-uri', + description: + 'if the actor is followed by this DID, contains the AT-URI of the follow record', + }, + }, + }, }, }, AppBskyGraphFollow: { @@ -7328,6 +7367,65 @@ export const schemaDict = { }, }, }, + AppBskyGraphGetRelationships: { + lexicon: 1, + id: 'app.bsky.graph.getRelationships', + defs: { + main: { + type: 'query', + description: + 'Enumerates public relationships between one account, and a list of other accounts', + parameters: { + type: 'params', + required: ['actor'], + properties: { + actor: { + type: 'string', + format: 'at-identifier', + }, + others: { + type: 'array', + maxLength: 30, + items: { + type: 'string', + format: 'at-identifier', + }, + }, + }, + }, + output: { + encoding: 'application/json', + schema: { + type: 'object', + required: ['relationships'], + properties: { + actor: { + type: 'string', + format: 'did', + }, + relationships: { + type: 'array', + items: { + type: 'union', + refs: [ + 'lex:app.bsky.graph.defs#relationship', + 'lex:app.bsky.graph.defs#notFoundActor', + ], + }, + }, + }, + }, + }, + errors: [ + { + name: 'ActorNotFound', + description: + 'the primary actor at-identifier could not be resolved', + }, + ], + }, + }, + }, AppBskyGraphGetSuggestedFollowsByActor: { lexicon: 1, id: 'app.bsky.graph.getSuggestedFollowsByActor', @@ -8272,6 +8370,7 @@ export const ids = { AppBskyGraphGetListMutes: 'app.bsky.graph.getListMutes', AppBskyGraphGetLists: 'app.bsky.graph.getLists', AppBskyGraphGetMutes: 'app.bsky.graph.getMutes', + AppBskyGraphGetRelationships: 'app.bsky.graph.getRelationships', AppBskyGraphGetSuggestedFollowsByActor: 'app.bsky.graph.getSuggestedFollowsByActor', AppBskyGraphList: 'app.bsky.graph.list', diff --git a/packages/api/src/client/types/app/bsky/graph/defs.ts b/packages/api/src/client/types/app/bsky/graph/defs.ts index 0b22401bcdf..0580b9bb158 100644 --- a/packages/api/src/client/types/app/bsky/graph/defs.ts +++ b/packages/api/src/client/types/app/bsky/graph/defs.ts @@ -102,3 +102,44 @@ export function isListViewerState(v: unknown): v is ListViewerState { export function validateListViewerState(v: unknown): ValidationResult { return lexicons.validate('app.bsky.graph.defs#listViewerState', v) } + +/** indicates that a handle or DID could not be resolved */ +export interface NotFoundActor { + actor: string + notFound: true + [k: string]: unknown +} + +export function isNotFoundActor(v: unknown): v is NotFoundActor { + return ( + isObj(v) && + hasProp(v, '$type') && + v.$type === 'app.bsky.graph.defs#notFoundActor' + ) +} + +export function validateNotFoundActor(v: unknown): ValidationResult { + return lexicons.validate('app.bsky.graph.defs#notFoundActor', v) +} + +/** lists the bi-directional graph relationships between one actor (not indicated in the object), and the target actors (the DID included in the object) */ +export interface Relationship { + did: string + /** if the actor follows this DID, this is the AT-URI of the follow record */ + following?: string + /** if the actor is followed by this DID, contains the AT-URI of the follow record */ + followedBy?: string + [k: string]: unknown +} + +export function isRelationship(v: unknown): v is Relationship { + return ( + isObj(v) && + hasProp(v, '$type') && + v.$type === 'app.bsky.graph.defs#relationship' + ) +} + +export function validateRelationship(v: unknown): ValidationResult { + return lexicons.validate('app.bsky.graph.defs#relationship', v) +} diff --git a/packages/api/src/client/types/app/bsky/graph/getRelationships.ts b/packages/api/src/client/types/app/bsky/graph/getRelationships.ts new file mode 100644 index 00000000000..5fce53f635c --- /dev/null +++ b/packages/api/src/client/types/app/bsky/graph/getRelationships.ts @@ -0,0 +1,49 @@ +/** + * 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' +import * as AppBskyGraphDefs from './defs' + +export interface QueryParams { + actor: string + others?: string[] +} + +export type InputSchema = undefined + +export interface OutputSchema { + actor?: string + relationships: ( + | AppBskyGraphDefs.Relationship + | AppBskyGraphDefs.NotFoundActor + | { $type: string; [k: string]: unknown } + )[] + [k: string]: unknown +} + +export interface CallOptions { + headers?: Headers +} + +export interface Response { + success: boolean + headers: Headers + data: OutputSchema +} + +export class ActorNotFoundError extends XRPCError { + constructor(src: XRPCError) { + super(src.status, src.error, src.message, src.headers) + } +} + +export function toKnownErr(e: any) { + if (e instanceof XRPCError) { + if (e.error === 'ActorNotFound') return new ActorNotFoundError(e) + } + return e +} diff --git a/packages/bsky/src/lexicon/index.ts b/packages/bsky/src/lexicon/index.ts index efdb35c319e..0e30f4d172c 100644 --- a/packages/bsky/src/lexicon/index.ts +++ b/packages/bsky/src/lexicon/index.ts @@ -114,6 +114,7 @@ import * as AppBskyGraphGetListBlocks from './types/app/bsky/graph/getListBlocks import * as AppBskyGraphGetListMutes from './types/app/bsky/graph/getListMutes' import * as AppBskyGraphGetLists from './types/app/bsky/graph/getLists' import * as AppBskyGraphGetMutes from './types/app/bsky/graph/getMutes' +import * as AppBskyGraphGetRelationships from './types/app/bsky/graph/getRelationships' import * as AppBskyGraphGetSuggestedFollowsByActor from './types/app/bsky/graph/getSuggestedFollowsByActor' import * as AppBskyGraphMuteActor from './types/app/bsky/graph/muteActor' import * as AppBskyGraphMuteActorList from './types/app/bsky/graph/muteActorList' @@ -1480,6 +1481,17 @@ export class AppBskyGraphNS { return this._server.xrpc.method(nsid, cfg) } + getRelationships( + cfg: ConfigOf< + AV, + AppBskyGraphGetRelationships.Handler>, + AppBskyGraphGetRelationships.HandlerReqCtx> + >, + ) { + const nsid = 'app.bsky.graph.getRelationships' // @ts-ignore + return this._server.xrpc.method(nsid, cfg) + } + getSuggestedFollowsByActor( cfg: ConfigOf< AV, diff --git a/packages/bsky/src/lexicon/lexicons.ts b/packages/bsky/src/lexicon/lexicons.ts index 0c757a80b0f..fea624e9a04 100644 --- a/packages/bsky/src/lexicon/lexicons.ts +++ b/packages/bsky/src/lexicon/lexicons.ts @@ -6925,6 +6925,45 @@ export const schemaDict = { }, }, }, + notFoundActor: { + type: 'object', + description: 'indicates that a handle or DID could not be resolved', + required: ['actor', 'notFound'], + properties: { + actor: { + type: 'string', + format: 'at-identifier', + }, + notFound: { + type: 'boolean', + const: true, + }, + }, + }, + relationship: { + type: 'object', + description: + 'lists the bi-directional graph relationships between one actor (not indicated in the object), and the target actors (the DID included in the object)', + required: ['did'], + properties: { + did: { + type: 'string', + format: 'did', + }, + following: { + type: 'string', + format: 'at-uri', + description: + 'if the actor follows this DID, this is the AT-URI of the follow record', + }, + followedBy: { + type: 'string', + format: 'at-uri', + description: + 'if the actor is followed by this DID, contains the AT-URI of the follow record', + }, + }, + }, }, }, AppBskyGraphFollow: { @@ -7328,6 +7367,65 @@ export const schemaDict = { }, }, }, + AppBskyGraphGetRelationships: { + lexicon: 1, + id: 'app.bsky.graph.getRelationships', + defs: { + main: { + type: 'query', + description: + 'Enumerates public relationships between one account, and a list of other accounts', + parameters: { + type: 'params', + required: ['actor'], + properties: { + actor: { + type: 'string', + format: 'at-identifier', + }, + others: { + type: 'array', + maxLength: 30, + items: { + type: 'string', + format: 'at-identifier', + }, + }, + }, + }, + output: { + encoding: 'application/json', + schema: { + type: 'object', + required: ['relationships'], + properties: { + actor: { + type: 'string', + format: 'did', + }, + relationships: { + type: 'array', + items: { + type: 'union', + refs: [ + 'lex:app.bsky.graph.defs#relationship', + 'lex:app.bsky.graph.defs#notFoundActor', + ], + }, + }, + }, + }, + }, + errors: [ + { + name: 'ActorNotFound', + description: + 'the primary actor at-identifier could not be resolved', + }, + ], + }, + }, + }, AppBskyGraphGetSuggestedFollowsByActor: { lexicon: 1, id: 'app.bsky.graph.getSuggestedFollowsByActor', @@ -8272,6 +8370,7 @@ export const ids = { AppBskyGraphGetListMutes: 'app.bsky.graph.getListMutes', AppBskyGraphGetLists: 'app.bsky.graph.getLists', AppBskyGraphGetMutes: 'app.bsky.graph.getMutes', + AppBskyGraphGetRelationships: 'app.bsky.graph.getRelationships', AppBskyGraphGetSuggestedFollowsByActor: 'app.bsky.graph.getSuggestedFollowsByActor', AppBskyGraphList: 'app.bsky.graph.list', diff --git a/packages/bsky/src/lexicon/types/app/bsky/graph/defs.ts b/packages/bsky/src/lexicon/types/app/bsky/graph/defs.ts index be2d8c385d9..31791dd3647 100644 --- a/packages/bsky/src/lexicon/types/app/bsky/graph/defs.ts +++ b/packages/bsky/src/lexicon/types/app/bsky/graph/defs.ts @@ -102,3 +102,44 @@ export function isListViewerState(v: unknown): v is ListViewerState { export function validateListViewerState(v: unknown): ValidationResult { return lexicons.validate('app.bsky.graph.defs#listViewerState', v) } + +/** indicates that a handle or DID could not be resolved */ +export interface NotFoundActor { + actor: string + notFound: true + [k: string]: unknown +} + +export function isNotFoundActor(v: unknown): v is NotFoundActor { + return ( + isObj(v) && + hasProp(v, '$type') && + v.$type === 'app.bsky.graph.defs#notFoundActor' + ) +} + +export function validateNotFoundActor(v: unknown): ValidationResult { + return lexicons.validate('app.bsky.graph.defs#notFoundActor', v) +} + +/** lists the bi-directional graph relationships between one actor (not indicated in the object), and the target actors (the DID included in the object) */ +export interface Relationship { + did: string + /** if the actor follows this DID, this is the AT-URI of the follow record */ + following?: string + /** if the actor is followed by this DID, contains the AT-URI of the follow record */ + followedBy?: string + [k: string]: unknown +} + +export function isRelationship(v: unknown): v is Relationship { + return ( + isObj(v) && + hasProp(v, '$type') && + v.$type === 'app.bsky.graph.defs#relationship' + ) +} + +export function validateRelationship(v: unknown): ValidationResult { + return lexicons.validate('app.bsky.graph.defs#relationship', v) +} diff --git a/packages/bsky/src/lexicon/types/app/bsky/graph/getRelationships.ts b/packages/bsky/src/lexicon/types/app/bsky/graph/getRelationships.ts new file mode 100644 index 00000000000..32a27434782 --- /dev/null +++ b/packages/bsky/src/lexicon/types/app/bsky/graph/getRelationships.ts @@ -0,0 +1,53 @@ +/** + * 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 AppBskyGraphDefs from './defs' + +export interface QueryParams { + actor: string + others?: string[] +} + +export type InputSchema = undefined + +export interface OutputSchema { + actor?: string + relationships: ( + | AppBskyGraphDefs.Relationship + | AppBskyGraphDefs.NotFoundActor + | { $type: string; [k: string]: unknown } + )[] + [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 + error?: 'ActorNotFound' +} + +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 diff --git a/packages/ozone/src/lexicon/index.ts b/packages/ozone/src/lexicon/index.ts index efdb35c319e..0e30f4d172c 100644 --- a/packages/ozone/src/lexicon/index.ts +++ b/packages/ozone/src/lexicon/index.ts @@ -114,6 +114,7 @@ import * as AppBskyGraphGetListBlocks from './types/app/bsky/graph/getListBlocks import * as AppBskyGraphGetListMutes from './types/app/bsky/graph/getListMutes' import * as AppBskyGraphGetLists from './types/app/bsky/graph/getLists' import * as AppBskyGraphGetMutes from './types/app/bsky/graph/getMutes' +import * as AppBskyGraphGetRelationships from './types/app/bsky/graph/getRelationships' import * as AppBskyGraphGetSuggestedFollowsByActor from './types/app/bsky/graph/getSuggestedFollowsByActor' import * as AppBskyGraphMuteActor from './types/app/bsky/graph/muteActor' import * as AppBskyGraphMuteActorList from './types/app/bsky/graph/muteActorList' @@ -1480,6 +1481,17 @@ export class AppBskyGraphNS { return this._server.xrpc.method(nsid, cfg) } + getRelationships( + cfg: ConfigOf< + AV, + AppBskyGraphGetRelationships.Handler>, + AppBskyGraphGetRelationships.HandlerReqCtx> + >, + ) { + const nsid = 'app.bsky.graph.getRelationships' // @ts-ignore + return this._server.xrpc.method(nsid, cfg) + } + getSuggestedFollowsByActor( cfg: ConfigOf< AV, diff --git a/packages/ozone/src/lexicon/lexicons.ts b/packages/ozone/src/lexicon/lexicons.ts index 0c757a80b0f..fea624e9a04 100644 --- a/packages/ozone/src/lexicon/lexicons.ts +++ b/packages/ozone/src/lexicon/lexicons.ts @@ -6925,6 +6925,45 @@ export const schemaDict = { }, }, }, + notFoundActor: { + type: 'object', + description: 'indicates that a handle or DID could not be resolved', + required: ['actor', 'notFound'], + properties: { + actor: { + type: 'string', + format: 'at-identifier', + }, + notFound: { + type: 'boolean', + const: true, + }, + }, + }, + relationship: { + type: 'object', + description: + 'lists the bi-directional graph relationships between one actor (not indicated in the object), and the target actors (the DID included in the object)', + required: ['did'], + properties: { + did: { + type: 'string', + format: 'did', + }, + following: { + type: 'string', + format: 'at-uri', + description: + 'if the actor follows this DID, this is the AT-URI of the follow record', + }, + followedBy: { + type: 'string', + format: 'at-uri', + description: + 'if the actor is followed by this DID, contains the AT-URI of the follow record', + }, + }, + }, }, }, AppBskyGraphFollow: { @@ -7328,6 +7367,65 @@ export const schemaDict = { }, }, }, + AppBskyGraphGetRelationships: { + lexicon: 1, + id: 'app.bsky.graph.getRelationships', + defs: { + main: { + type: 'query', + description: + 'Enumerates public relationships between one account, and a list of other accounts', + parameters: { + type: 'params', + required: ['actor'], + properties: { + actor: { + type: 'string', + format: 'at-identifier', + }, + others: { + type: 'array', + maxLength: 30, + items: { + type: 'string', + format: 'at-identifier', + }, + }, + }, + }, + output: { + encoding: 'application/json', + schema: { + type: 'object', + required: ['relationships'], + properties: { + actor: { + type: 'string', + format: 'did', + }, + relationships: { + type: 'array', + items: { + type: 'union', + refs: [ + 'lex:app.bsky.graph.defs#relationship', + 'lex:app.bsky.graph.defs#notFoundActor', + ], + }, + }, + }, + }, + }, + errors: [ + { + name: 'ActorNotFound', + description: + 'the primary actor at-identifier could not be resolved', + }, + ], + }, + }, + }, AppBskyGraphGetSuggestedFollowsByActor: { lexicon: 1, id: 'app.bsky.graph.getSuggestedFollowsByActor', @@ -8272,6 +8370,7 @@ export const ids = { AppBskyGraphGetListMutes: 'app.bsky.graph.getListMutes', AppBskyGraphGetLists: 'app.bsky.graph.getLists', AppBskyGraphGetMutes: 'app.bsky.graph.getMutes', + AppBskyGraphGetRelationships: 'app.bsky.graph.getRelationships', AppBskyGraphGetSuggestedFollowsByActor: 'app.bsky.graph.getSuggestedFollowsByActor', AppBskyGraphList: 'app.bsky.graph.list', diff --git a/packages/ozone/src/lexicon/types/app/bsky/graph/defs.ts b/packages/ozone/src/lexicon/types/app/bsky/graph/defs.ts index be2d8c385d9..31791dd3647 100644 --- a/packages/ozone/src/lexicon/types/app/bsky/graph/defs.ts +++ b/packages/ozone/src/lexicon/types/app/bsky/graph/defs.ts @@ -102,3 +102,44 @@ export function isListViewerState(v: unknown): v is ListViewerState { export function validateListViewerState(v: unknown): ValidationResult { return lexicons.validate('app.bsky.graph.defs#listViewerState', v) } + +/** indicates that a handle or DID could not be resolved */ +export interface NotFoundActor { + actor: string + notFound: true + [k: string]: unknown +} + +export function isNotFoundActor(v: unknown): v is NotFoundActor { + return ( + isObj(v) && + hasProp(v, '$type') && + v.$type === 'app.bsky.graph.defs#notFoundActor' + ) +} + +export function validateNotFoundActor(v: unknown): ValidationResult { + return lexicons.validate('app.bsky.graph.defs#notFoundActor', v) +} + +/** lists the bi-directional graph relationships between one actor (not indicated in the object), and the target actors (the DID included in the object) */ +export interface Relationship { + did: string + /** if the actor follows this DID, this is the AT-URI of the follow record */ + following?: string + /** if the actor is followed by this DID, contains the AT-URI of the follow record */ + followedBy?: string + [k: string]: unknown +} + +export function isRelationship(v: unknown): v is Relationship { + return ( + isObj(v) && + hasProp(v, '$type') && + v.$type === 'app.bsky.graph.defs#relationship' + ) +} + +export function validateRelationship(v: unknown): ValidationResult { + return lexicons.validate('app.bsky.graph.defs#relationship', v) +} diff --git a/packages/ozone/src/lexicon/types/app/bsky/graph/getRelationships.ts b/packages/ozone/src/lexicon/types/app/bsky/graph/getRelationships.ts new file mode 100644 index 00000000000..32a27434782 --- /dev/null +++ b/packages/ozone/src/lexicon/types/app/bsky/graph/getRelationships.ts @@ -0,0 +1,53 @@ +/** + * 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 AppBskyGraphDefs from './defs' + +export interface QueryParams { + actor: string + others?: string[] +} + +export type InputSchema = undefined + +export interface OutputSchema { + actor?: string + relationships: ( + | AppBskyGraphDefs.Relationship + | AppBskyGraphDefs.NotFoundActor + | { $type: string; [k: string]: unknown } + )[] + [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 + error?: 'ActorNotFound' +} + +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 diff --git a/packages/pds/src/lexicon/index.ts b/packages/pds/src/lexicon/index.ts index efdb35c319e..0e30f4d172c 100644 --- a/packages/pds/src/lexicon/index.ts +++ b/packages/pds/src/lexicon/index.ts @@ -114,6 +114,7 @@ import * as AppBskyGraphGetListBlocks from './types/app/bsky/graph/getListBlocks import * as AppBskyGraphGetListMutes from './types/app/bsky/graph/getListMutes' import * as AppBskyGraphGetLists from './types/app/bsky/graph/getLists' import * as AppBskyGraphGetMutes from './types/app/bsky/graph/getMutes' +import * as AppBskyGraphGetRelationships from './types/app/bsky/graph/getRelationships' import * as AppBskyGraphGetSuggestedFollowsByActor from './types/app/bsky/graph/getSuggestedFollowsByActor' import * as AppBskyGraphMuteActor from './types/app/bsky/graph/muteActor' import * as AppBskyGraphMuteActorList from './types/app/bsky/graph/muteActorList' @@ -1480,6 +1481,17 @@ export class AppBskyGraphNS { return this._server.xrpc.method(nsid, cfg) } + getRelationships( + cfg: ConfigOf< + AV, + AppBskyGraphGetRelationships.Handler>, + AppBskyGraphGetRelationships.HandlerReqCtx> + >, + ) { + const nsid = 'app.bsky.graph.getRelationships' // @ts-ignore + return this._server.xrpc.method(nsid, cfg) + } + getSuggestedFollowsByActor( cfg: ConfigOf< AV, diff --git a/packages/pds/src/lexicon/lexicons.ts b/packages/pds/src/lexicon/lexicons.ts index 0c757a80b0f..fea624e9a04 100644 --- a/packages/pds/src/lexicon/lexicons.ts +++ b/packages/pds/src/lexicon/lexicons.ts @@ -6925,6 +6925,45 @@ export const schemaDict = { }, }, }, + notFoundActor: { + type: 'object', + description: 'indicates that a handle or DID could not be resolved', + required: ['actor', 'notFound'], + properties: { + actor: { + type: 'string', + format: 'at-identifier', + }, + notFound: { + type: 'boolean', + const: true, + }, + }, + }, + relationship: { + type: 'object', + description: + 'lists the bi-directional graph relationships between one actor (not indicated in the object), and the target actors (the DID included in the object)', + required: ['did'], + properties: { + did: { + type: 'string', + format: 'did', + }, + following: { + type: 'string', + format: 'at-uri', + description: + 'if the actor follows this DID, this is the AT-URI of the follow record', + }, + followedBy: { + type: 'string', + format: 'at-uri', + description: + 'if the actor is followed by this DID, contains the AT-URI of the follow record', + }, + }, + }, }, }, AppBskyGraphFollow: { @@ -7328,6 +7367,65 @@ export const schemaDict = { }, }, }, + AppBskyGraphGetRelationships: { + lexicon: 1, + id: 'app.bsky.graph.getRelationships', + defs: { + main: { + type: 'query', + description: + 'Enumerates public relationships between one account, and a list of other accounts', + parameters: { + type: 'params', + required: ['actor'], + properties: { + actor: { + type: 'string', + format: 'at-identifier', + }, + others: { + type: 'array', + maxLength: 30, + items: { + type: 'string', + format: 'at-identifier', + }, + }, + }, + }, + output: { + encoding: 'application/json', + schema: { + type: 'object', + required: ['relationships'], + properties: { + actor: { + type: 'string', + format: 'did', + }, + relationships: { + type: 'array', + items: { + type: 'union', + refs: [ + 'lex:app.bsky.graph.defs#relationship', + 'lex:app.bsky.graph.defs#notFoundActor', + ], + }, + }, + }, + }, + }, + errors: [ + { + name: 'ActorNotFound', + description: + 'the primary actor at-identifier could not be resolved', + }, + ], + }, + }, + }, AppBskyGraphGetSuggestedFollowsByActor: { lexicon: 1, id: 'app.bsky.graph.getSuggestedFollowsByActor', @@ -8272,6 +8370,7 @@ export const ids = { AppBskyGraphGetListMutes: 'app.bsky.graph.getListMutes', AppBskyGraphGetLists: 'app.bsky.graph.getLists', AppBskyGraphGetMutes: 'app.bsky.graph.getMutes', + AppBskyGraphGetRelationships: 'app.bsky.graph.getRelationships', AppBskyGraphGetSuggestedFollowsByActor: 'app.bsky.graph.getSuggestedFollowsByActor', AppBskyGraphList: 'app.bsky.graph.list', diff --git a/packages/pds/src/lexicon/types/app/bsky/graph/defs.ts b/packages/pds/src/lexicon/types/app/bsky/graph/defs.ts index be2d8c385d9..31791dd3647 100644 --- a/packages/pds/src/lexicon/types/app/bsky/graph/defs.ts +++ b/packages/pds/src/lexicon/types/app/bsky/graph/defs.ts @@ -102,3 +102,44 @@ export function isListViewerState(v: unknown): v is ListViewerState { export function validateListViewerState(v: unknown): ValidationResult { return lexicons.validate('app.bsky.graph.defs#listViewerState', v) } + +/** indicates that a handle or DID could not be resolved */ +export interface NotFoundActor { + actor: string + notFound: true + [k: string]: unknown +} + +export function isNotFoundActor(v: unknown): v is NotFoundActor { + return ( + isObj(v) && + hasProp(v, '$type') && + v.$type === 'app.bsky.graph.defs#notFoundActor' + ) +} + +export function validateNotFoundActor(v: unknown): ValidationResult { + return lexicons.validate('app.bsky.graph.defs#notFoundActor', v) +} + +/** lists the bi-directional graph relationships between one actor (not indicated in the object), and the target actors (the DID included in the object) */ +export interface Relationship { + did: string + /** if the actor follows this DID, this is the AT-URI of the follow record */ + following?: string + /** if the actor is followed by this DID, contains the AT-URI of the follow record */ + followedBy?: string + [k: string]: unknown +} + +export function isRelationship(v: unknown): v is Relationship { + return ( + isObj(v) && + hasProp(v, '$type') && + v.$type === 'app.bsky.graph.defs#relationship' + ) +} + +export function validateRelationship(v: unknown): ValidationResult { + return lexicons.validate('app.bsky.graph.defs#relationship', v) +} diff --git a/packages/pds/src/lexicon/types/app/bsky/graph/getRelationships.ts b/packages/pds/src/lexicon/types/app/bsky/graph/getRelationships.ts new file mode 100644 index 00000000000..32a27434782 --- /dev/null +++ b/packages/pds/src/lexicon/types/app/bsky/graph/getRelationships.ts @@ -0,0 +1,53 @@ +/** + * 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 AppBskyGraphDefs from './defs' + +export interface QueryParams { + actor: string + others?: string[] +} + +export type InputSchema = undefined + +export interface OutputSchema { + actor?: string + relationships: ( + | AppBskyGraphDefs.Relationship + | AppBskyGraphDefs.NotFoundActor + | { $type: string; [k: string]: unknown } + )[] + [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 + error?: 'ActorNotFound' +} + +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