Thread viewer for Bluesky

avoid using {object} type for params

object is apparently equal to "any" in JSDoc types

+9 -9
api.js
··· 92 92 this.profiles = {}; 93 93 } 94 94 95 - /** @param {object} author */ 95 + /** @param {json} author */ 96 96 97 97 cacheProfile(author) { 98 98 this.profiles[author.did] = author; ··· 157 157 } 158 158 } 159 159 160 - /** @param {string} url, @returns {Promise<object>} */ 160 + /** @param {string} url, @returns {Promise<json>} */ 161 161 162 162 async loadThreadByURL(url) { 163 163 let [handle, postId] = BlueskyAPI.parsePostURL(url); 164 164 return await this.loadThreadById(handle, postId); 165 165 } 166 166 167 - /** @param {string} author, @param {string} postId, @returns {Promise<object>} */ 167 + /** @param {string} author, @param {string} postId, @returns {Promise<json>} */ 168 168 169 169 async loadThreadById(author, postId) { 170 170 let did = author.startsWith('did:') ? author : await this.resolveHandle(author); ··· 173 173 return threadJSON; 174 174 } 175 175 176 - /** @param {string} handle, @returns {Promise<object>} */ 176 + /** @param {string} handle, @returns {Promise<json>} */ 177 177 178 178 async loadUserProfile(handle) { 179 179 if (this.profiles[handle]) { ··· 204 204 return json.quoteCount; 205 205 } 206 206 207 - /** @param {string} url, @param {string | undefined} cursor, @returns {Promise<object>} */ 207 + /** @param {string} url, @param {string | undefined} cursor, @returns {Promise<json>} */ 208 208 209 209 async getQuotes(url, cursor = undefined) { 210 210 let [handle, postId] = BlueskyAPI.parsePostURL(url); ··· 220 220 return await this.getRequest('eu.mackuba.private.getPostQuotes', params); 221 221 } 222 222 223 - /** @param {string} hashtag, @param {string | undefined} cursor, @returns {Promise<object>} */ 223 + /** @param {string} hashtag, @param {string | undefined} cursor, @returns {Promise<json>} */ 224 224 225 225 async getHashtagFeed(hashtag, cursor = undefined) { 226 226 let params = { q: '#' + hashtag, limit: 50, sort: 'latest' }; ··· 232 232 return await this.getRequest('app.bsky.feed.searchPosts', params); 233 233 } 234 234 235 - /** @param {string} postURI, @returns {Promise<object>} */ 235 + /** @param {string} postURI, @returns {Promise<json>} */ 236 236 237 237 async loadPost(postURI) { 238 238 let posts = await this.loadPosts([postURI]); ··· 250 250 } 251 251 } 252 252 253 - /** @param {object} post, @returns {Promise<object>} */ 253 + /** @param {Post} post, @returns {Promise<json>} */ 254 254 255 255 async likePost(post) { 256 256 return await this.postRequest('com.atproto.repo.createRecord', { ··· 266 266 }); 267 267 } 268 268 269 - /** @param {string} uri, @returns {Promise<object>} */ 269 + /** @param {string} uri, @returns {Promise<void>} */ 270 270 271 271 async removeLike(uri) { 272 272 let { rkey } = atURI(uri);
+10 -10
minisky.js
··· 4 4 5 5 class APIError extends Error { 6 6 7 - /** @param {number} code, @param {object} json */ 7 + /** @param {number} code, @param {json} json */ 8 8 constructor(code, json) { 9 9 super("APIError status " + code + "\n\n" + JSON.stringify(json)); 10 10 this.code = code; ··· 106 106 * @prop {string | boolean} [auth] 107 107 * @prop {Record<string, string>} [headers] 108 108 * 109 - * @param {string} method, @param {object} params, @param {MiniskyRequestOptions} [options] 110 - * @returns {Promise<object>} 109 + * @param {string} method, @param {json | null} [params], @param {MiniskyRequestOptions} [options] 110 + * @returns {Promise<json>} 111 111 */ 112 112 113 113 async getRequest(method, params, options) { ··· 139 139 } 140 140 141 141 /** 142 - * @param {string} method, @param {object} [data], @param {MiniskyRequestOptions} [options] 143 - * @returns Promise<object> 142 + * @param {string} method, @param {json | null} [data], @param {MiniskyRequestOptions} [options] 143 + * @returns Promise<json> 144 144 */ 145 145 146 146 async postRequest(method, data, options) { ··· 200 200 return exp * 1000; 201 201 } 202 202 203 - /** @param {Response} response, @param {object} json, @returns {boolean} */ 203 + /** @param {Response} response, @param {json} json, @returns {boolean} */ 204 204 205 205 isInvalidToken(response, json) { 206 206 return (response.status == 400) && !!json && ['InvalidToken', 'ExpiredToken'].includes(json.error); 207 207 } 208 208 209 - /** @param {Response} response, @returns {Promise<object>} */ 209 + /** @param {Response} response, @returns {Promise<json>} */ 210 210 211 211 async parseResponse(response) { 212 212 let text = await response.text(); ··· 233 233 } 234 234 } 235 235 236 - /** @param {string} handle, @param {string} password, @returns {Promise<object>} */ 236 + /** @param {string} handle, @param {string} password, @returns {Promise<json>} */ 237 237 238 238 async logIn(handle, password) { 239 239 let params = { identifier: handle, password: password }; ··· 243 243 return json; 244 244 } 245 245 246 - /** @returns {Promise<object>} */ 246 + /** @returns {Promise<json>} */ 247 247 248 248 async performTokenRefresh() { 249 249 console.log('Refreshing access token…'); ··· 252 252 return json; 253 253 } 254 254 255 - /** @param {object} json */ 255 + /** @param {json} json */ 256 256 257 257 saveTokens(json) { 258 258 this.user.accessToken = json['accessJwt'];
+21 -21
models.js
··· 17 17 18 18 class ATProtoRecord { 19 19 20 - /** @param {object} data, @param {object} [extra] */ 20 + /** @param {json} data, @param {json} [extra] */ 21 21 constructor(data, extra) { 22 22 this.data = data; 23 23 Object.assign(this, extra ?? {}); ··· 65 65 * View of a post as part of a thread, as returned from getPostThread. 66 66 * Expected to be #threadViewPost, but may be blocked or missing. 67 67 * 68 - * @param {object} json, @returns {AnyPost} 68 + * @param {json} json, @returns {AnyPost} 69 69 */ 70 70 71 71 static parseThreadPost(json) { ··· 99 99 * Expected to be app.bsky.embed.record#viewRecord, but may be blocked, missing or a different type of record 100 100 * (e.g. a list or a feed generator). For unknown record embeds, we fall back to generic ATProtoRecord. 101 101 * 102 - * @param {object} json, @returns {ATProtoRecord} 102 + * @param {json} json, @returns {ATProtoRecord} 103 103 */ 104 104 105 105 static parseViewRecord(json) { ··· 129 129 * View of a post as part of a feed (e.g. a profile feed, home timeline or a custom feed). It should be an 130 130 * app.bsky.feed.defs#feedViewPost - blocked or missing posts don't appear here, they just aren't included. 131 131 * 132 - * @param {object} json, @returns {Post} 132 + * @param {json} json, @returns {Post} 133 133 */ 134 134 135 135 static parseFeedPost(json) { ··· 151 151 * a blocked or missing post. The #postView must include a $type. 152 152 * (This is used for e.g. parent/root of a #feedViewPost.) 153 153 * 154 - * @param {object} json, @returns {AnyPost} 154 + * @param {json} json, @returns {AnyPost} 155 155 */ 156 156 157 157 static parsePostView(json) { ··· 170 170 } 171 171 } 172 172 173 - /** @param {object} data, @param {object} [extra] */ 173 + /** @param {json} data, @param {json} [extra] */ 174 174 175 175 constructor(data, extra) { 176 176 super(data); ··· 238 238 return this.record.text; 239 239 } 240 240 241 - /** @returns {object} */ 241 + /** @returns {json} */ 242 242 get facets() { 243 243 return this.record.facets; 244 244 } ··· 307 307 308 308 class BlockedPost extends ATProtoRecord { 309 309 310 - /** @param {object} data */ 310 + /** @param {json} data */ 311 311 constructor(data) { 312 312 super(data); 313 313 this.author = data.author; ··· 338 338 339 339 class FeedGeneratorRecord extends ATProtoRecord { 340 340 341 - /** @param {object} data */ 341 + /** @param {json} data */ 342 342 constructor(data) { 343 343 super(data); 344 344 this.author = data.creator; ··· 372 372 373 373 class UserListRecord extends ATProtoRecord { 374 374 375 - /** @param {object} data */ 375 + /** @param {json} data */ 376 376 constructor(data) { 377 377 super(data); 378 378 this.author = data.creator; ··· 409 409 /** 410 410 * More hydrated view of an embed, taken from a full post view (#postView). 411 411 * 412 - * @param {object} json, @returns {Embed} 412 + * @param {json} json, @returns {Embed} 413 413 */ 414 414 415 415 static parseInlineEmbed(json) { ··· 439 439 /** 440 440 * Raw embed extracted from raw record data of a post. Does not include quoted post contents. 441 441 * 442 - * @param {object} json, @returns {Embed} 442 + * @param {json} json, @returns {Embed} 443 443 */ 444 444 445 445 static parseRawEmbed(json) { ··· 466 466 } 467 467 } 468 468 469 - /** @param {object} json */ 469 + /** @param {json} json */ 470 470 constructor(json) { 471 471 this.json = json; 472 472 } ··· 479 479 480 480 class RawImageEmbed extends Embed { 481 481 482 - /** @param {object} json */ 482 + /** @param {json} json */ 483 483 constructor(json) { 484 484 super(json); 485 485 this.images = json.images; ··· 488 488 489 489 class RawLinkEmbed extends Embed { 490 490 491 - /** @param {object} json */ 491 + /** @param {json} json */ 492 492 constructor(json) { 493 493 super(json); 494 494 ··· 499 499 500 500 class RawRecordEmbed extends Embed { 501 501 502 - /** @param {object} json */ 502 + /** @param {json} json */ 503 503 constructor(json) { 504 504 super(json); 505 505 this.record = new ATProtoRecord(json.record); ··· 508 508 509 509 class RawRecordWithMediaEmbed extends Embed { 510 510 511 - /** @param {object} json */ 511 + /** @param {json} json */ 512 512 constructor(json) { 513 513 super(json); 514 514 this.record = new ATProtoRecord(json.record.record); ··· 520 520 521 521 /** 522 522 * app.bsky.embed.record#view 523 - * @param {object} json 523 + * @param {json} json 524 524 */ 525 525 constructor(json) { 526 526 super(json); ··· 532 532 533 533 /** 534 534 * app.bsky.embed.recordWithMedia#view 535 - * @param {object} json 535 + * @param {json} json 536 536 */ 537 537 constructor(json) { 538 538 super(json); ··· 545 545 546 546 /** 547 547 * app.bsky.embed.external#view 548 - * @param {object} json 548 + * @param {json} json 549 549 */ 550 550 constructor(json) { 551 551 super(json); ··· 560 560 561 561 /** 562 562 * app.bsky.embed.images#view 563 - * @param {object} json 563 + * @param {json} json 564 564 */ 565 565 constructor(json) { 566 566 super(json);
+1 -1
post_component.js
··· 43 43 } 44 44 } 45 45 46 - /** @returns {object} */ 46 + /** @returns {json} */ 47 47 get timeFormatForTimestamp() { 48 48 if (this.isRoot) { 49 49 return { day: 'numeric', month: 'short', year: 'numeric', hour: 'numeric', minute: 'numeric' };
+2 -2
rich_text_lite.js
··· 26 26 // packages/api/src/rich-text/rich-text.ts 27 27 28 28 class RichTextSegment { 29 - /** @param {string} text, @param {object} [facet] */ 29 + /** @param {string} text, @param {json} [facet] */ 30 30 constructor(text, facet) { 31 31 this.text = text; 32 32 this.facet = facet; ··· 49 49 } 50 50 51 51 class RichText { 52 - /** @params {object} props */ 52 + /** @params {json} props */ 53 53 constructor(props) { 54 54 this.unicodeText = new UnicodeString(props.text); 55 55 this.facets = props.facets;
+1
types.d.ts
··· 10 10 declare var isIncognito: boolean; 11 11 12 12 type SomeElement = Element | HTMLElement | AnyElement; 13 + type json = Record<string, any>; 13 14 14 15 interface AnyElement { 15 16 classList: CSSClassList;