@steve31415/baselib 3.38.0 → 3.38.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -96,7 +96,9 @@ export class TwitterApiIoClient {
96
96
  const unique = [...new Set(ids)];
97
97
  for (let i = 0; i < unique.length; i += 100) {
98
98
  const result = await this.tweets('/tweets', { tweet_ids: unique.slice(i, i + 100).join(',') });
99
- tweets.push(...result.tweets);
99
+ // An unavailable tweet comes back as a stub with an empty id and no
100
+ // author (live, 2026-10-15); it is not a tweet, so drop it here.
101
+ tweets.push(...result.tweets.filter((t) => t.id && t.author));
100
102
  apiCalls += result.apiCalls ?? 1;
101
103
  }
102
104
  return { tweets, apiCalls };
package/dist/twitter.js CHANGED
@@ -26,8 +26,8 @@ export function compareTweetIds(a, b) {
26
26
  return a.length - b.length;
27
27
  return a.localeCompare(b);
28
28
  }
29
- const sameAuthor = (a, b) => !!(a.author.id && b.author.id && a.author.id === b.author.id) ||
30
- !!(a.author.userName && b.author.userName && a.author.userName.toLowerCase() === b.author.userName.toLowerCase());
29
+ const sameAuthor = (a, b) => !!(a.author?.id && b.author?.id && a.author.id === b.author.id) ||
30
+ !!(a.author?.userName && b.author?.userName && a.author.userName.toLowerCase() === b.author.userName.toLowerCase());
31
31
  export function expandTweetUrls(tweet) {
32
32
  let text = tweet.text;
33
33
  const unmatched = [];
@@ -119,7 +119,7 @@ export async function assembleThread(id, options) {
119
119
  };
120
120
  /** `conversation_id:<cid> from:<author>` — the author's replies Mirror may lack. */
121
121
  const searchAuthor = async (author, cid) => {
122
- if (!/^\w+$/.test(author.author.userName)) {
122
+ if (!/^\w+$/.test(author.author?.userName ?? '')) {
123
123
  warning('Twitter conversation author handle missing or invalid');
124
124
  return;
125
125
  }
@@ -282,14 +282,14 @@ export async function assembleThread(id, options) {
282
282
  if (!root && !rootFailed)
283
283
  warning(`Root ${cid} not found`);
284
284
  else if (root) {
285
- const archived = !!conversation?.complete && followed.has(root.author.userName.toLowerCase());
285
+ const archived = !!conversation?.complete && followed.has((root.author?.userName ?? '').toLowerCase());
286
286
  incompleteWarning('the root author');
287
287
  if (!archived)
288
288
  await searchAuthor(root, cid);
289
289
  }
290
290
  const candidates = () => [linked, ...[...records.values()].map((r) => r.tweet)
291
291
  .filter((tweet) => tweet.id !== linked.id && (tweet.conversationId || cid) === cid &&
292
- (tweet.id === cid || (!!root && sameAuthor(tweet, root)) || followed.has(tweet.author.userName.toLowerCase())))
292
+ (tweet.id === cid || (!!root && sameAuthor(tweet, root)) || followed.has((tweet.author?.userName ?? '').toLowerCase())))
293
293
  .sort((a, b) => compareTweetIds(a.id, b.id))];
294
294
  // Fill parents missing from every candidate's chain, one batch per depth.
295
295
  let lookups = 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@steve31415/baselib",
3
- "version": "3.38.0",
3
+ "version": "3.38.1",
4
4
  "description": "Plasticine new-world shared platform library: logging, auth, service-to-service auth, db, HTTP, sync, app updates",
5
5
  "type": "module",
6
6
  "license": "MIT",