@@ -60,6 +60,17 @@ export interface EnsuredDiscussion {
6060 number : number ;
6161}
6262
63+ export interface DiscussionContent {
64+ readonly discussion : Record < string , unknown > ;
65+ readonly comments : readonly Record < string , unknown > [ ] ;
66+ }
67+
68+ export interface AddedComment {
69+ readonly id : string ;
70+ readonly body ?: string ;
71+ readonly url ?: string ;
72+ }
73+
6374export class FeedbackClient {
6475 readonly #apiOrigin: string ;
6576 readonly #site: string ;
@@ -124,7 +135,7 @@ export class FeedbackClient {
124135 if ( normalized . length === 0 ) throw new TypeError ( "At least one resource key is required" ) ;
125136 const pending = normalized . filter ( ( key ) => this . #viewerNeedsSync( key , token . viewerId ) ) ;
126137 if ( pending . length > 0 ) {
127- const url = new URL ( `/v1/sites/${ encodeURIComponent ( this . #site) } /viewer-reactions ` , this . #apiOrigin) ;
138+ const url = new URL ( `/v1/sites/${ encodeURIComponent ( this . #site) } /viewer` , this . #apiOrigin) ;
128139 url . searchParams . set ( "keys" , pending . join ( "," ) ) ;
129140 const headers = { Accept : "application/json" , Authorization : `Bearer ${ token . value } ` } ;
130141 const init : RequestInit = { headers } ;
@@ -197,6 +208,45 @@ export class FeedbackClient {
197208 return { id : payload . id , number : payload . number } ;
198209 }
199210
211+ async discussionContent ( key : string , signal ?: AbortSignal ) : Promise < DiscussionContent > {
212+ validateResourceId ( key ) ;
213+ const url = new URL ( `/v1/sites/${ encodeURIComponent ( this . #site) } /discussion` , this . #apiOrigin) ;
214+ url . searchParams . set ( "keys" , key ) ;
215+ const init : RequestInit = { headers : { Accept : "application/json" } } ;
216+ if ( signal ) init . signal = signal ;
217+ const response = await this . #fetch( url , init ) ;
218+ if ( ! response . ok ) throw new FeedbackError ( response . status , await errorCode ( response ) ) ;
219+ const payload : unknown = await response . json ( ) ;
220+ if ( ! payload || typeof payload !== "object" || ( payload as { v ?: unknown } ) . v !== 1 ) {
221+ throw new TypeError ( "Invalid discussion content response" ) ;
222+ }
223+ const content = ( payload as { content ?: unknown } ) . content ;
224+ if ( ! content || typeof content !== "object" ) throw new TypeError ( "Invalid discussion content response" ) ;
225+ return { discussion : content as Record < string , unknown > , comments : [ ] } ;
226+ }
227+
228+ async addComment (
229+ key : string ,
230+ body : string ,
231+ token : AccessToken ,
232+ replyTo ?: string ,
233+ signal ?: AbortSignal ,
234+ ) : Promise < AddedComment > {
235+ validateResourceId ( key ) ;
236+ if ( ! body . trim ( ) || body . length > 16_000 ) throw new TypeError ( "Invalid comment body" ) ;
237+ const payload = await this . #post(
238+ "comments" ,
239+ { key, body, ...( replyTo === undefined ? { } : { reply_to : replyTo } ) } ,
240+ signal ,
241+ token . value ,
242+ ) ;
243+ const comment = payload . comment ;
244+ if ( ! comment || typeof comment !== "object" || typeof ( comment as { id ?: unknown } ) . id !== "string" ) {
245+ throw new TypeError ( "Invalid comment response" ) ;
246+ }
247+ return comment as AddedComment ;
248+ }
249+
200250 async vote (
201251 key : string ,
202252 requested : Vote ,
0 commit comments