initial public commit

This commit is contained in:
2026-02-22 21:26:15 -05:00
commit 9dbf7ae796
100 changed files with 18823 additions and 0 deletions

83
dist-node/parseTwtxt.js Normal file
View File

@@ -0,0 +1,83 @@
import dayjs from "dayjs";
import utc from "dayjs/plugin/utc.js";
import hashTwt from "./hashTwt.js";
import { getValueOrFirstEntry } from "./utils.js";
dayjs.extend(utc);
function parseTwtxt(twtxt) {
const allLines = twtxt.split("\n");
const { commentLines = [], contentLines = [] } = allLines.reduce(
(acc, originalLine) => {
const line = originalLine.trim();
if (line === "") return acc;
if (line.startsWith("#")) acc.commentLines.push(line);
else acc.contentLines.push(line);
return acc;
},
{
commentLines: [],
contentLines: []
}
);
const { following = [], metadata = {} } = commentLines.filter((line) => line.includes("=")).reduce(
(acc, line) => {
const [key, ...vals] = line.substring(1).split("=").map((field) => field.trim());
const val = vals.join("=");
if (key === "follow") {
const [nick, url] = val.trim().split(/\s+/);
acc.following.push({ nick, url });
} else {
if (acc.metadata[key]) {
if (!Array.isArray(acc.metadata[key]))
acc.metadata[key] = [acc.metadata[key], val];
else acc.metadata[key].push(val);
} else acc.metadata[key] = val;
}
return acc;
},
{
following: [],
metadata: {}
}
);
const replyRegEx = /\(#([\w]+)\) (\<\@(\S+) ([^>]+)>)*/;
const twts = contentLines.map((line) => {
const [created, content] = line.split(/\t/).map((val) => val.trim());
if (typeof content === "undefined")
throw new Error(`Content is undefined: ${line}`);
const createdDayjs = dayjs.utc(created);
if (!createdDayjs.isValid())
throw new Error(`Date is invalid: ${line}`);
const createdUTC = createdDayjs.toISOString();
const replyMatches = replyRegEx.exec(content);
let replyHash, replyNick, replyUrl;
if (replyMatches?.length) {
replyHash = replyMatches?.[1];
replyNick = replyMatches?.[3];
replyUrl = replyMatches?.[4];
}
const hash = hashTwt({
content,
created,
createdUTC,
url: getValueOrFirstEntry(metadata?.url ?? "")
});
return {
content,
created,
createdUTC,
hash,
replyHash,
replyNick,
replyUrl
};
}).sort((a, b) => dayjs(a.created).diff(dayjs(b.created)));
return {
following,
metadata,
twts
};
}
export {
parseTwtxt as default
};
//# sourceMappingURL=parseTwtxt.js.map