read.js
1 import { cli, Strategy } from '@jackwener/opencli/registry'; 2 import { EmptyResultError } from '@jackwener/opencli/errors'; 3 import { DOMAIN, SITE, gqlEscape, gqlRequest, parsePostId, stripHtml, } from './_helpers.js'; 4 cli({ 5 site: SITE, 6 name: 'read', 7 description: 'Read full post by URL or ID', 8 domain: DOMAIN, 9 strategy: Strategy.PUBLIC, 10 browser: false, 11 args: [ 12 { 13 name: 'url-or-id', 14 type: 'string', 15 required: true, 16 positional: true, 17 help: 'Post URL or LessWrong post ID', 18 }, 19 ], 20 columns: ['title', 'author', 'karma', 'comments', 'tags', 'content', 'url'], 21 func: async (_page, kwargs) => { 22 const postId = parsePostId(String(kwargs['url-or-id'])); 23 const query = `query PostsSingle { 24 post(input: {selector: {documentId: "${gqlEscape(postId)}"}}) { 25 result { _id title user { displayName } baseScore commentCount htmlBody slug postedAt tags { name } } 26 } 27 }`; 28 const data = await gqlRequest(query); 29 const post = data?.post?.result; 30 if (!post?._id) { 31 throw new EmptyResultError('lesswrong read', `Post "${postId}" not found`); 32 } 33 return [ 34 { 35 title: post.title ?? '', 36 author: post.user?.displayName ?? 'Unknown', 37 karma: post.baseScore ?? 0, 38 comments: post.commentCount ?? 0, 39 tags: (post.tags ?? []).map((tag) => tag.name ?? '').filter(Boolean).join(', '), 40 content: stripHtml(post.htmlBody ?? ''), 41 url: `https://${DOMAIN}/posts/${post._id}/${post.slug}`, 42 }, 43 ]; 44 }, 45 });