diff --git a/models/article.ts b/models/article.ts index d9ca80b..5b423d0 100644 --- a/models/article.ts +++ b/models/article.ts @@ -48,6 +48,14 @@ export default class Article { return this.event.created_at; } + get content(): string { + return this.event.content; + } + + get isDeleted(): boolean { + return !!this.event.tags.find((t) => t[0] === "deleted"); + } + get naddr(): string { return nip19.naddrEncode({ identifier: this.identifier, diff --git a/nostr.ts b/nostr.ts index 7ea7ace..03ff19a 100644 --- a/nostr.ts +++ b/nostr.ts @@ -61,9 +61,12 @@ export async function fetchArticlesByAuthor( }]) as NostrEvent[]; const articles = events.map((a) => new Article(a)); - const sortedArticles = articles.sort((a, b) => b.publishedAt - a.publishedAt); - // The limit seems to apply per relay, not per pool query - return sortedArticles.slice(0, limit); + + return articles + .filter((a) => !a.isDeleted) + .filter((a) => a.content.trim() !== "") + .sort((a, b) => b.publishedAt - a.publishedAt) + .slice(0, limit); // The limit seems to apply per relay, not per pool query } export async function fetchProfileEvent(pubkey: string) { diff --git a/tests/fixtures/article-deleted.json b/tests/fixtures/article-deleted.json new file mode 100644 index 0000000..6cf147b --- /dev/null +++ b/tests/fixtures/article-deleted.json @@ -0,0 +1,9 @@ +{ + "content": "", + "created_at": 1716761766, + "id": "ae83c3e23e11db5fd0e6dacaece38847451e81d1429e4182a0cadd409bdce30f", + "kind": 30023, + "pubkey": "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d", + "sig": "6c21eba5324af302dfbfb9dadfc2d067646a3594ffed02d2528cca8ee0f7c16b9ffb3dc640420304882be94e789d93191d830108ac52d57b2e72445025e433b2", + "tags": [["d", "66674915"], ["deleted"]] +} diff --git a/tests/models/article_test.ts b/tests/models/article_test.ts index 99835f1..4519ec7 100644 --- a/tests/models/article_test.ts +++ b/tests/models/article_test.ts @@ -1,17 +1,18 @@ import { beforeAll, describe, it } from "@std/testing/bdd"; import { expect } from "@std/expect"; -import { NostrEvent as NEvent } from "@nostrify/nostrify"; import Article from "../../models/article.ts"; describe("Article", () => { - let articleEvent: NEvent; let article: Article; + let deletedArticle: Article; beforeAll(() => { - articleEvent = JSON.parse( + article = new Article(JSON.parse( Deno.readTextFileSync("tests/fixtures/article-1.json"), - ); - article = new Article(articleEvent); + )); + deletedArticle = new Article(JSON.parse( + Deno.readTextFileSync("tests/fixtures/article-deleted.json"), + )); }); describe("#identifier", () => { @@ -58,6 +59,13 @@ describe("Article", () => { }); }); + describe("#isDeleted", () => { + it("returns a boolean based on the 'deleted' tag", () => { + expect(article.isDeleted).toEqual(false); + expect(deletedArticle.isDeleted).toEqual(true); + }); + }); + describe("#naddr", () => { it("returns a bech32 addressable event ID", () => { expect(article.naddr).toMatch(