@k34a/blog 0.0.19 → 0.0.21
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.
|
@@ -4,20 +4,20 @@ import { Box as o, Stack as g, Title as f, Text as s, Flex as h, Badge as u } fr
|
|
|
4
4
|
import { IconHash as x } from "@tabler/icons-react";
|
|
5
5
|
import { BannerImage as D } from "./banner-image.js";
|
|
6
6
|
import w from "./description.js";
|
|
7
|
-
import { calculateReadingTime as
|
|
7
|
+
import { calculateReadingTime as y } from "../utils.js";
|
|
8
8
|
function I(e) {
|
|
9
|
-
const
|
|
9
|
+
const a = new Date(e.created_at), r = new Date(e.updated_at), n = (i) => i.toLocaleDateString("en-US", {
|
|
10
10
|
year: "numeric",
|
|
11
11
|
month: "long",
|
|
12
12
|
day: "numeric"
|
|
13
|
-
}), m = e.description.replace(/<[^>]*>/g, " ").replace(/\s+/g, " ").trim(), d =
|
|
13
|
+
}), m = e.description.replace(/<[^>]*>/g, " ").replace(/\s+/g, " ").trim(), d = y(m), l = n(r) !== n(a);
|
|
14
14
|
return /* @__PURE__ */ t(o, { maw: 800, mx: "auto", px: "sm", py: "lg", children: /* @__PURE__ */ c(g, { gap: "md", children: [
|
|
15
15
|
/* @__PURE__ */ t(f, { order: 1, children: e.title }),
|
|
16
16
|
/* @__PURE__ */ c(s, { size: "sm", c: "dimmed", children: [
|
|
17
17
|
d.text,
|
|
18
18
|
" · Written on ",
|
|
19
|
-
|
|
20
|
-
l && ` · Updated on ${r
|
|
19
|
+
n(a),
|
|
20
|
+
l && ` · Updated on ${n(r)}`
|
|
21
21
|
] }),
|
|
22
22
|
e.banner_image && /* @__PURE__ */ t(
|
|
23
23
|
D,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { articleSortByVsQuery as
|
|
1
|
+
import { articleSortByVsQuery as m } from "./search-params.js";
|
|
2
2
|
import "zod";
|
|
3
|
-
import { PAGE_SIZE as
|
|
4
|
-
class
|
|
3
|
+
import { PAGE_SIZE as f } from "../cfg.js";
|
|
4
|
+
class I {
|
|
5
5
|
db;
|
|
6
6
|
constructor(e) {
|
|
7
7
|
this.db = e;
|
|
@@ -14,22 +14,22 @@ class q {
|
|
|
14
14
|
const { data: t, error: r } = await this.db.from("articles").select("*").eq("slug", e).eq("status", "Published").single();
|
|
15
15
|
if (r)
|
|
16
16
|
return console.error("Error fetching article details:", r.message), null;
|
|
17
|
-
const { data:
|
|
18
|
-
if (
|
|
17
|
+
const { data: a, error: o } = await this.db.from("tag_articles").select("tag_id").eq("article_id", t.id);
|
|
18
|
+
if (o)
|
|
19
19
|
return console.error(
|
|
20
20
|
"Error fetching article tag links:",
|
|
21
|
-
|
|
21
|
+
o.message
|
|
22
22
|
), { ...t, tags: [] };
|
|
23
|
-
const
|
|
24
|
-
let
|
|
25
|
-
if (
|
|
26
|
-
const { data: c, error:
|
|
27
|
-
|
|
23
|
+
const i = a?.map((c) => c.tag_id) || [];
|
|
24
|
+
let n = [];
|
|
25
|
+
if (i.length > 0) {
|
|
26
|
+
const { data: c, error: s } = await this.db.from("tags").select("name").in("id", i);
|
|
27
|
+
s ? console.error(
|
|
28
28
|
"Error fetching article tag names:",
|
|
29
|
-
|
|
30
|
-
) :
|
|
29
|
+
s.message
|
|
30
|
+
) : n = c.map((l) => l.name);
|
|
31
31
|
}
|
|
32
|
-
return { ...t, tags:
|
|
32
|
+
return { ...t, tags: n };
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
35
|
* Get total number of articles.
|
|
@@ -48,37 +48,28 @@ class q {
|
|
|
48
48
|
const { data: e, error: t } = await this.db.from("tags").select("name");
|
|
49
49
|
return t ? (console.error("Error fetching tags:", t.message), []) : e?.map((r) => r.name) ?? [];
|
|
50
50
|
}
|
|
51
|
+
getUniqueIdsInOrder(e) {
|
|
52
|
+
const t = /* @__PURE__ */ new Set(), r = [];
|
|
53
|
+
for (const a of e)
|
|
54
|
+
t.has(a.id) || (t.add(a.id), r.push(a.id));
|
|
55
|
+
return r;
|
|
56
|
+
}
|
|
51
57
|
/**
|
|
52
58
|
* Paginated list of articles with filters and sorting.
|
|
53
59
|
*/
|
|
54
60
|
async list(e) {
|
|
55
|
-
const { page: t, search: r, sortBy:
|
|
56
|
-
let
|
|
57
|
-
r && (
|
|
58
|
-
const { data:
|
|
59
|
-
if (
|
|
60
|
-
return console.error("Count failed:",
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if (f)
|
|
68
|
-
return console.error("Error fetching paginated articles:", f), { items: [], total: 0 };
|
|
69
|
-
const m = /* @__PURE__ */ new Map();
|
|
70
|
-
for (const a of b ?? [])
|
|
71
|
-
m.has(a.id) || m.set(a.id, {
|
|
72
|
-
id: a.id,
|
|
73
|
-
title: a.title,
|
|
74
|
-
description: a.description,
|
|
75
|
-
slug: a.slug,
|
|
76
|
-
created_at: a.created_at,
|
|
77
|
-
banner_image: a.banner_image
|
|
78
|
-
});
|
|
79
|
-
return {
|
|
80
|
-
items: [...m.values()],
|
|
81
|
-
total: d
|
|
61
|
+
const { page: t, search: r, sortBy: a, tags: o } = e, i = m[a] ?? m.latest, n = t * f, c = n + f - 1;
|
|
62
|
+
let s = this.db.from("article_with_tags").select("id", { count: "exact" }).eq("status", "Published");
|
|
63
|
+
r && (s = s.ilike("title", `%${r}%`)), o && o.length > 0 && (s = s.in("tag", o)), s = s.order(i.column, { ascending: i.ascending });
|
|
64
|
+
const { data: l, error: d } = await s;
|
|
65
|
+
if (d)
|
|
66
|
+
return console.error("Count failed:", d), { items: [], total: 0 };
|
|
67
|
+
const g = new Set(l?.map((p) => p.id)).size, h = this.getUniqueIdsInOrder(l).slice(n, c + 1), { data: b, error: u } = await this.db.from("articles").select(
|
|
68
|
+
"id,title,description,slug,created_at,banner_image"
|
|
69
|
+
).in("id", h).eq("status", "Published").order(i.column, { ascending: i.ascending });
|
|
70
|
+
return u ? (console.error("Error fetching articles:", u), { items: [], total: g }) : {
|
|
71
|
+
items: b ?? [],
|
|
72
|
+
total: g
|
|
82
73
|
};
|
|
83
74
|
}
|
|
84
75
|
async getDescription(e) {
|
|
@@ -92,5 +83,5 @@ class q {
|
|
|
92
83
|
}
|
|
93
84
|
}
|
|
94
85
|
export {
|
|
95
|
-
|
|
86
|
+
I as ArticleService
|
|
96
87
|
};
|