@seedprotocol/feed 0.4.20 → 0.4.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.
- package/README.md +2 -0
- package/dist/config.d.ts +3 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/consume/parseRss.d.ts +9 -0
- package/dist/consume/parseRss.d.ts.map +1 -0
- package/dist/feedFieldStorageModel.d.ts +12 -0
- package/dist/feedFieldStorageModel.d.ts.map +1 -0
- package/dist/getFeedItems.d.ts.map +1 -1
- package/dist/hydrateArweaveRichText.d.ts +11 -0
- package/dist/hydrateArweaveRichText.d.ts.map +1 -0
- package/dist/imageRelationEnrichment.d.ts +6 -0
- package/dist/imageRelationEnrichment.d.ts.map +1 -0
- package/dist/index.d.ts +9 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1289 -932
- package/dist/index.js.map +1 -1
- package/dist/listRelationKey.d.ts +13 -0
- package/dist/listRelationKey.d.ts.map +1 -0
- package/dist/parseEasPropertyMetadataForFeed.d.ts +25 -0
- package/dist/parseEasPropertyMetadataForFeed.d.ts.map +1 -0
- package/dist/pickFeedItemRichText.d.ts +19 -0
- package/dist/pickFeedItemRichText.d.ts.map +1 -0
- package/dist/rss/generateRssXml.d.ts.map +1 -1
- package/dist/types.d.ts +17 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -1,22 +1,168 @@
|
|
|
1
|
-
import { BaseArweaveClient as
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
1
|
+
import { BaseArweaveClient as De, getSeedsBySchemaName as We, withExcludeRevokedFilter as Se, EasClient as Te, getItemVersionsFromEas as He, getItemPropertiesFromEas as ze, pickLatestPropertyAttestationsByRefAndSchema as Ge, setSchemaUidForSchemaDefinition as Je, DEFAULT_ARWEAVE_GATEWAYS as Ee, client as L, DEFAULT_ARWEAVE_HOST as Xe } from "@seedprotocol/sdk";
|
|
2
|
+
import { classifyMediaRef as on, getFeedItemStringField as cn, normalizeFeedItemFields as ln, resolveMediaRef as dn } from "@seedprotocol/sdk";
|
|
3
|
+
import { gql as Ve } from "graphql-request";
|
|
4
|
+
import b from "pluralize";
|
|
5
|
+
import Ye from "rss-parser";
|
|
6
|
+
import { generateJsonFeed as Ke, generateAtomFeed as qe } from "feedsmith";
|
|
7
|
+
import { create as Ze } from "xmlbuilder2";
|
|
8
|
+
import { createHash as Qe } from "crypto";
|
|
9
|
+
import { promises as I } from "fs";
|
|
8
10
|
import { join as U } from "path";
|
|
9
|
-
import
|
|
10
|
-
function
|
|
11
|
-
return `https://${
|
|
11
|
+
import le from "image-size";
|
|
12
|
+
function j(t) {
|
|
13
|
+
return `https://${De.getHost()}/${t}`;
|
|
12
14
|
}
|
|
13
|
-
function
|
|
14
|
-
const
|
|
15
|
-
return { itemUrlBase:
|
|
15
|
+
function G() {
|
|
16
|
+
const t = process.env.FEED_ITEM_URL_BASE?.trim() || "https://optimism-sepolia.easscan.org", e = process.env.FEED_ITEM_URL_PATH?.trim() || "attestation/view", n = process.env.FEED_SITE_URL?.trim() || "https://seedprotocol.io", s = process.env.FEED_EXPAND_RELATIONS?.toLowerCase() !== "false", r = parseInt(process.env.FEED_PAGE_SIZE || "25", 10), a = process.env.FEED_INCLUDE_DATA_URI_HTML_ITEMS?.toLowerCase() === "true" ? "include_items" : "omit_items";
|
|
17
|
+
return { itemUrlBase: t, itemUrlPath: e, siteUrl: n, expandRelations: s, pageSize: r, richTextDataUriImages: a };
|
|
16
18
|
}
|
|
17
|
-
const
|
|
19
|
+
const et = /^(.+?)([A-Z][a-zA-Z]+)Ids$/;
|
|
20
|
+
function oe(t) {
|
|
21
|
+
const e = et.exec(t);
|
|
22
|
+
if (e) {
|
|
23
|
+
const n = e[1];
|
|
24
|
+
if (n) return b(n);
|
|
25
|
+
}
|
|
26
|
+
if (t.endsWith("_ids")) {
|
|
27
|
+
const n = t.slice(0, -4), s = n.split("_").filter(Boolean);
|
|
28
|
+
if (s.length >= 2) {
|
|
29
|
+
const r = s[0];
|
|
30
|
+
return r.endsWith("s") ? r : b(r);
|
|
31
|
+
}
|
|
32
|
+
return b(n);
|
|
33
|
+
}
|
|
34
|
+
return t;
|
|
35
|
+
}
|
|
36
|
+
function Ae(t, e) {
|
|
37
|
+
for (const n of Object.keys(t))
|
|
38
|
+
n !== e && oe(n) === e && delete t[n];
|
|
39
|
+
}
|
|
40
|
+
function Ie(t) {
|
|
41
|
+
if (Array.isArray(t) || typeof t != "string") return t;
|
|
42
|
+
const e = t.trim();
|
|
43
|
+
if (!e.startsWith("[")) return t;
|
|
44
|
+
try {
|
|
45
|
+
const n = JSON.parse(e);
|
|
46
|
+
if (Array.isArray(n)) return n;
|
|
47
|
+
} catch {
|
|
48
|
+
}
|
|
49
|
+
return t;
|
|
50
|
+
}
|
|
51
|
+
function tt(t) {
|
|
52
|
+
const e = t.storageTransactionId ?? t.storage_transaction_id;
|
|
53
|
+
if (e && typeof e == "string" && e.trim())
|
|
54
|
+
try {
|
|
55
|
+
t.arweaveUrl = j(e.trim());
|
|
56
|
+
} catch {
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const nt = /* @__PURE__ */ new Set(["html", "file", "json"]), _e = "_feedFieldStorageModels", $e = "_feedListElementStorageModels";
|
|
60
|
+
function Z(t) {
|
|
61
|
+
return t.trim().toLowerCase();
|
|
62
|
+
}
|
|
63
|
+
function B(t) {
|
|
64
|
+
return nt.has(Z(t));
|
|
65
|
+
}
|
|
66
|
+
function de(t) {
|
|
67
|
+
const e = Z(t);
|
|
68
|
+
return e === "html" ? 0 : e === "file" ? 1 : e === "json" ? 2 : 99;
|
|
69
|
+
}
|
|
70
|
+
function Q(t) {
|
|
71
|
+
const e = t[_e];
|
|
72
|
+
if (e !== null && typeof e == "object" && !Array.isArray(e))
|
|
73
|
+
return e;
|
|
74
|
+
}
|
|
75
|
+
function ee(t) {
|
|
76
|
+
const e = t[$e];
|
|
77
|
+
if (e !== null && typeof e == "object" && !Array.isArray(e))
|
|
78
|
+
return e;
|
|
79
|
+
}
|
|
80
|
+
function fe(t, e, n) {
|
|
81
|
+
const s = Z(n);
|
|
82
|
+
let r = Q(t);
|
|
83
|
+
r || (r = {}, t[_e] = r), r[e] = s;
|
|
84
|
+
}
|
|
85
|
+
function rt(t, e, n) {
|
|
86
|
+
let s = ee(t);
|
|
87
|
+
s || (s = {}, t[$e] = s), s[e] = n.map(Z);
|
|
88
|
+
}
|
|
89
|
+
const at = ["html", "Html", "body", "Body", "content", "Content"], st = 2e6;
|
|
90
|
+
function Me(t) {
|
|
91
|
+
const e = t.trim();
|
|
92
|
+
if (!e.startsWith("http://") && !e.startsWith("https://")) return !1;
|
|
93
|
+
try {
|
|
94
|
+
const n = new URL(e), s = n.hostname.toLowerCase(), r = De.getHost().toLowerCase();
|
|
95
|
+
if (s !== r && !s.endsWith("arweave.net")) return !1;
|
|
96
|
+
const a = n.pathname.replace(/^\//, "").split("/").filter(Boolean);
|
|
97
|
+
if (a.length !== 1) return !1;
|
|
98
|
+
const o = a[0];
|
|
99
|
+
return /^[A-Za-z0-9_-]{43}$/.test(o);
|
|
100
|
+
} catch {
|
|
101
|
+
return !1;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
async function Fe(t) {
|
|
105
|
+
try {
|
|
106
|
+
const e = await fetch(t, {
|
|
107
|
+
headers: { Accept: "text/html, text/plain, text/markdown, application/json, */*" },
|
|
108
|
+
signal: AbortSignal.timeout(15e3)
|
|
109
|
+
});
|
|
110
|
+
if (!e.ok) return null;
|
|
111
|
+
const n = e.headers.get("content-type") ?? "";
|
|
112
|
+
if (/^(image|video|audio)\//i.test(n)) return null;
|
|
113
|
+
const s = await e.arrayBuffer();
|
|
114
|
+
if (s.byteLength > st) return null;
|
|
115
|
+
const r = new TextDecoder("utf-8", { fatal: !1 }).decode(s);
|
|
116
|
+
return r.length === 0 || r.includes("\0") ? null : r;
|
|
117
|
+
} catch {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
async function ot(t, e) {
|
|
122
|
+
const n = t[e];
|
|
123
|
+
if (typeof n != "string" || n.trim() === "" || !Me(n)) return;
|
|
124
|
+
const s = await Fe(n);
|
|
125
|
+
s !== null && (t[e] = s);
|
|
126
|
+
}
|
|
127
|
+
async function it(t) {
|
|
128
|
+
for (const e of t) {
|
|
129
|
+
const n = /* @__PURE__ */ new Set([...at]), s = Q(e);
|
|
130
|
+
if (s)
|
|
131
|
+
for (const [a, o] of Object.entries(s))
|
|
132
|
+
B(o) && n.add(a);
|
|
133
|
+
for (const a of n)
|
|
134
|
+
await ot(e, a);
|
|
135
|
+
const r = ee(e);
|
|
136
|
+
if (r)
|
|
137
|
+
for (const [a, o] of Object.entries(r)) {
|
|
138
|
+
const i = e[a];
|
|
139
|
+
if (!Array.isArray(i)) continue;
|
|
140
|
+
const c = Math.min(o.length, i.length);
|
|
141
|
+
for (let d = 0; d < c; d++) {
|
|
142
|
+
if (!B(o[d])) continue;
|
|
143
|
+
const f = i[d];
|
|
144
|
+
if (typeof f != "string" || !Me(f)) continue;
|
|
145
|
+
const p = await Fe(f);
|
|
146
|
+
p !== null && (i[d] = p);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
function ct(t) {
|
|
152
|
+
const e = typeof t == "string" ? t.trim() : "";
|
|
153
|
+
if (!e)
|
|
154
|
+
return { ok: !1, reason: "empty" };
|
|
155
|
+
let n;
|
|
156
|
+
try {
|
|
157
|
+
n = JSON.parse(e);
|
|
158
|
+
} catch (r) {
|
|
159
|
+
return { ok: !1, reason: "parse", error: r };
|
|
160
|
+
}
|
|
161
|
+
return !Array.isArray(n) || n.length === 0 || !n[0]?.value ? { ok: !1, reason: "shape" } : { ok: !0, metadata: n[0].value };
|
|
162
|
+
}
|
|
163
|
+
const J = "image", N = [
|
|
18
164
|
"0x0000000000000000000000000000000000000000000000000000000000000020"
|
|
19
|
-
],
|
|
165
|
+
], Ue = Ve`
|
|
20
166
|
query GetSeeds($where: AttestationWhereInput!, $take: Int, $skip: Int) {
|
|
21
167
|
itemSeeds: attestations(where: $where, orderBy: [{ timeCreated: desc }], take: $take, skip: $skip) {
|
|
22
168
|
id
|
|
@@ -34,107 +180,123 @@ const L = [
|
|
|
34
180
|
isOffchain
|
|
35
181
|
}
|
|
36
182
|
}
|
|
37
|
-
`,
|
|
38
|
-
const e = new Date(
|
|
39
|
-
return `${
|
|
40
|
-
},
|
|
41
|
-
const [e,
|
|
42
|
-
if (!e || !
|
|
43
|
-
const
|
|
44
|
-
return { propertyName: e.endsWith("s") ? e : e + "s", modelName:
|
|
45
|
-
},
|
|
46
|
-
const { itemUrlBase:
|
|
47
|
-
!
|
|
48
|
-
const i =
|
|
49
|
-
let
|
|
183
|
+
`, H = (t) => t.replace(/_([a-z])/g, (e, n) => n.toUpperCase()), lt = (t) => {
|
|
184
|
+
const e = new Date(t * 1e3), n = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], s = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], r = n[e.getUTCDay()], a = s[e.getUTCMonth()], o = e.getUTCFullYear(), i = e.getUTCDate().toString().padStart(2, "0"), c = e.getUTCHours().toString().padStart(2, "0"), d = e.getUTCMinutes().toString().padStart(2, "0"), f = e.getUTCSeconds().toString().padStart(2, "0");
|
|
185
|
+
return `${r}, ${i} ${a} ${o} ${c}:${d}:${f} GMT`;
|
|
186
|
+
}, dt = (t) => t === "image" ? "images" : t === "post" ? "posts" : t.toLowerCase() + "s", ft = (t) => {
|
|
187
|
+
const [e, n, s] = t.split("_");
|
|
188
|
+
if (!e || !n) return null;
|
|
189
|
+
const r = s === "ids";
|
|
190
|
+
return { propertyName: e.endsWith("s") ? e : e + "s", modelName: n, isList: r };
|
|
191
|
+
}, ne = (t, e, n, s) => {
|
|
192
|
+
const { itemUrlBase: r, itemUrlPath: a, siteUrl: o } = s;
|
|
193
|
+
!t.title && !t.Title ? (t.title = e, t.Title = e) : t.title && !t.Title ? t.Title = t.title : t.Title && !t.title && (t.title = t.Title);
|
|
194
|
+
const i = t.storage_transaction_id && typeof t.storage_transaction_id == "string" && t.storage_transaction_id.trim() !== "" && t.storage_transaction_id !== "undefined" && t.storage_transaction_id !== e ? t.storage_transaction_id.trim() : null, c = t.storageTransactionId && typeof t.storageTransactionId == "string" && t.storageTransactionId.trim() !== "" && t.storageTransactionId !== "undefined" && t.storageTransactionId !== e ? t.storageTransactionId.trim() : null, d = i || c, f = dt(n), p = e && typeof e == "string" && e.trim() !== "" ? e : "unknown";
|
|
195
|
+
let w;
|
|
50
196
|
if (d && d !== e && d.length > 0)
|
|
51
197
|
try {
|
|
52
|
-
|
|
53
|
-
} catch (
|
|
54
|
-
console.error("[feed] [setFeedItemDefaults] Error generating Arweave URL:",
|
|
198
|
+
w = j(d);
|
|
199
|
+
} catch (m) {
|
|
200
|
+
console.error("[feed] [setFeedItemDefaults] Error generating Arweave URL:", m), r != null ? w = `${r.replace(/\/$/, "")}/${(a ?? "attestation/view").replace(/^\//, "")}/${p}` : w = `${o.replace(/\/$/, "")}/${f}/${p}`;
|
|
55
201
|
}
|
|
56
202
|
else
|
|
57
|
-
|
|
58
|
-
const
|
|
59
|
-
!
|
|
60
|
-
const
|
|
61
|
-
if (!
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
} else
|
|
65
|
-
!
|
|
66
|
-
},
|
|
67
|
-
function
|
|
68
|
-
|
|
203
|
+
r != null ? w = `${r.replace(/\/$/, "")}/${(a ?? "attestation/view").replace(/^\//, "")}/${p}` : w = `${o.replace(/\/$/, "")}/${f}/${p}`;
|
|
204
|
+
const h = t.link || t.Link;
|
|
205
|
+
!h || h === "undefined" || typeof h == "string" && h.trim() === "" ? (t.link = w, t.Link = w) : ((!t.link || t.link === "undefined") && (t.link = h), (!t.Link || t.Link === "undefined") && (t.Link = h));
|
|
206
|
+
const C = t.guid || t.Guid;
|
|
207
|
+
if (!C || C === "undefined" || typeof C == "string" && C.trim() === "" ? (t.guid = t.link || w, t.Guid = t.guid) : ((!t.guid || t.guid === "undefined") && (t.guid = C), (!t.Guid || t.Guid === "undefined") && (t.Guid = C)), t.timeCreated && !t.pubDate && !t.PubDate) {
|
|
208
|
+
const m = lt(t.timeCreated);
|
|
209
|
+
t.pubDate = m, t.PubDate = m;
|
|
210
|
+
} else t.pubDate && !t.PubDate ? t.PubDate = t.pubDate : t.PubDate && !t.pubDate && (t.pubDate = t.PubDate);
|
|
211
|
+
!t.seedUid && !t.SeedUid ? (t.seedUid = e, t.SeedUid = e) : t.seedUid && !t.SeedUid ? t.SeedUid = t.seedUid : t.SeedUid && !t.seedUid && (t.seedUid = t.SeedUid), t.attester && !t.Attester ? t.Attester = t.attester : t.Attester && !t.attester && (t.attester = t.Attester);
|
|
212
|
+
}, F = /* @__PURE__ */ new Map(), Y = /* @__PURE__ */ new Set(), ie = /* @__PURE__ */ new Map(), $ = /* @__PURE__ */ new Map(), X = /* @__PURE__ */ new Map(), be = /* @__PURE__ */ new Map();
|
|
213
|
+
function ht() {
|
|
214
|
+
F.clear(), Y.clear(), ie.clear(), $.clear(), X.clear(), be.clear();
|
|
69
215
|
}
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
216
|
+
const ut = async (t, e) => {
|
|
217
|
+
const n = ct(t.decodedDataJson);
|
|
218
|
+
if (!n.ok) {
|
|
219
|
+
const { id: m, refUID: y, schemaId: l } = t;
|
|
220
|
+
n.reason === "empty" ? console.warn(
|
|
221
|
+
"[feed] [processItemProperty] empty decodedDataJson for property:",
|
|
222
|
+
m,
|
|
223
|
+
y,
|
|
224
|
+
l
|
|
225
|
+
) : n.reason === "parse" ? console.warn(
|
|
226
|
+
"[feed] [processItemProperty] failed to parse decodedDataJson for property:",
|
|
227
|
+
m,
|
|
228
|
+
y,
|
|
229
|
+
l,
|
|
230
|
+
n.error
|
|
231
|
+
) : console.warn(
|
|
232
|
+
"[feed] [processItemProperty] invalid decodedDataJson structure for property:",
|
|
233
|
+
m,
|
|
234
|
+
y,
|
|
235
|
+
l
|
|
236
|
+
);
|
|
76
237
|
return;
|
|
77
238
|
}
|
|
78
|
-
|
|
79
|
-
|
|
239
|
+
const s = n.metadata;
|
|
240
|
+
let r = s.name;
|
|
241
|
+
if (!r)
|
|
80
242
|
return;
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
text:
|
|
84
|
-
schemaUid:
|
|
243
|
+
const a = t.schemaId;
|
|
244
|
+
Je({
|
|
245
|
+
text: r,
|
|
246
|
+
schemaUid: a
|
|
85
247
|
});
|
|
86
|
-
let
|
|
87
|
-
const
|
|
88
|
-
if (
|
|
89
|
-
if (
|
|
90
|
-
if (
|
|
91
|
-
const
|
|
92
|
-
|
|
248
|
+
let o = !1, i = !1;
|
|
249
|
+
const c = s.type, d = (c === "bytes32" || c === "bytes32[]") && r !== "storage_transaction_id" && r !== "storage_provider_transaction_id", f = !d && (r.endsWith("_id") || r.endsWith("_ids")) && r !== "storage_transaction_id" && r !== "storage_provider_transaction_id";
|
|
250
|
+
if (d || f)
|
|
251
|
+
if (o = !0, Array.isArray(s.value)) {
|
|
252
|
+
if (i = !0, f) {
|
|
253
|
+
const m = ft(r);
|
|
254
|
+
m && (r = m.propertyName);
|
|
93
255
|
}
|
|
94
|
-
|
|
95
|
-
|
|
256
|
+
s.value.forEach((m) => {
|
|
257
|
+
N.includes(m) || Y.add(m);
|
|
96
258
|
});
|
|
97
|
-
} else
|
|
98
|
-
let
|
|
99
|
-
typeof
|
|
100
|
-
(
|
|
259
|
+
} else N.includes(s.value) || Y.add(s.value);
|
|
260
|
+
let p = s.value;
|
|
261
|
+
o && i && Array.isArray(p) ? p = p.map((m) => String(m)) : typeof p != "string" && (p = JSON.stringify(p)), o && !i && e.find((y) => y.id === s.value)?.schema?.schemaNames, o && i && e.filter(
|
|
262
|
+
(y) => Array.isArray(s.value) && s.value.includes(y.id)
|
|
101
263
|
).length > 0;
|
|
102
|
-
const
|
|
103
|
-
if (!
|
|
264
|
+
const w = ie.get(t.refUID);
|
|
265
|
+
if (!w)
|
|
104
266
|
return;
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
},
|
|
110
|
-
const e =
|
|
111
|
-
for (let
|
|
112
|
-
const i =
|
|
267
|
+
const h = $.get(w) || {};
|
|
268
|
+
h[r] = p;
|
|
269
|
+
const C = H(r);
|
|
270
|
+
C !== r && (h[C] = p), $.set(w, h);
|
|
271
|
+
}, he = async (t) => {
|
|
272
|
+
const e = t.map((o) => o.id);
|
|
273
|
+
for (let o = 0; o < t.length; o++) {
|
|
274
|
+
const i = t[o];
|
|
113
275
|
if (!i) continue;
|
|
114
276
|
e.push(i.id);
|
|
115
|
-
const
|
|
116
|
-
|
|
277
|
+
const c = i.schema?.schemaNames?.[0]?.name ?? "unknown";
|
|
278
|
+
F.set(i.id, c), $.has(i.id) || $.set(i.id, {
|
|
117
279
|
seedUid: i.id,
|
|
118
280
|
timeCreated: i.timeCreated,
|
|
119
281
|
attester: i.attester
|
|
120
282
|
});
|
|
121
283
|
}
|
|
122
|
-
const
|
|
123
|
-
for (let
|
|
124
|
-
const i =
|
|
125
|
-
|
|
126
|
-
const d =
|
|
127
|
-
|
|
284
|
+
const n = await He({ seedUids: e });
|
|
285
|
+
for (let o = 0; o < n.length; o++) {
|
|
286
|
+
const i = n[o], c = i.refUID;
|
|
287
|
+
ie.set(i.id, c);
|
|
288
|
+
const d = X.get(c) || [];
|
|
289
|
+
X.set(c, [...d, i]);
|
|
128
290
|
}
|
|
129
|
-
const
|
|
130
|
-
for (const [
|
|
291
|
+
const s = [];
|
|
292
|
+
for (const [o, i] of X.entries()) {
|
|
131
293
|
const d = [...i].sort((f, p) => p.timeCreated - f.timeCreated)[0];
|
|
132
|
-
d && (
|
|
294
|
+
d && (s.push(d.id), be.set(o, d.id));
|
|
133
295
|
}
|
|
134
|
-
const
|
|
135
|
-
for (let
|
|
136
|
-
await
|
|
137
|
-
},
|
|
296
|
+
const r = await ze({ versionUids: s }), a = Ge(r);
|
|
297
|
+
for (let o = 0; o < a.length; o++)
|
|
298
|
+
await ut(a[o], t);
|
|
299
|
+
}, ve = /* @__PURE__ */ new Set([
|
|
138
300
|
"seedUid",
|
|
139
301
|
"SeedUid",
|
|
140
302
|
"timeCreated",
|
|
@@ -145,56 +307,69 @@ const Ne = async (a, e) => {
|
|
|
145
307
|
"storageTransactionId",
|
|
146
308
|
"storageProviderTransactionId"
|
|
147
309
|
]);
|
|
148
|
-
function
|
|
149
|
-
const e = Array.from(
|
|
150
|
-
([
|
|
310
|
+
function gt(t) {
|
|
311
|
+
const e = Array.from($.entries()).filter(
|
|
312
|
+
([n]) => F.get(n) === t
|
|
151
313
|
);
|
|
152
|
-
for (const [,
|
|
153
|
-
const
|
|
154
|
-
(
|
|
314
|
+
for (const [, n] of e) {
|
|
315
|
+
const s = Object.keys(n).filter(
|
|
316
|
+
(r) => !r.startsWith("_") && !ve.has(r)
|
|
155
317
|
);
|
|
156
|
-
for (const
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
318
|
+
for (const r of s) {
|
|
319
|
+
let a = n[r];
|
|
320
|
+
const o = Ie(a);
|
|
321
|
+
if (o !== a && Array.isArray(o) && (n[r] = o, a = o), Array.isArray(a)) {
|
|
322
|
+
const c = a;
|
|
323
|
+
if (!c.some(
|
|
324
|
+
(h) => typeof h == "string" && !N.includes(h) && $.has(h)
|
|
162
325
|
)) continue;
|
|
163
|
-
const
|
|
164
|
-
let
|
|
165
|
-
for (const
|
|
166
|
-
if (typeof
|
|
167
|
-
|
|
326
|
+
const f = [], p = [];
|
|
327
|
+
let w = !1;
|
|
328
|
+
for (const h of c) {
|
|
329
|
+
if (typeof h != "string" || N.includes(h)) {
|
|
330
|
+
f.push(String(h)), p.push("unknown");
|
|
168
331
|
continue;
|
|
169
332
|
}
|
|
170
|
-
const
|
|
171
|
-
if (
|
|
333
|
+
const C = F.get(h) ?? "unknown";
|
|
334
|
+
if (C === J) {
|
|
335
|
+
f.push(h), p.push(J);
|
|
336
|
+
continue;
|
|
337
|
+
}
|
|
338
|
+
const m = $.get(h), y = m?.storageTransactionId ?? m?.storage_transaction_id;
|
|
339
|
+
if (y && typeof y == "string" && y.trim())
|
|
172
340
|
try {
|
|
173
|
-
|
|
341
|
+
f.push(j(y)), p.push(C), w = !0;
|
|
174
342
|
} catch {
|
|
175
|
-
|
|
343
|
+
f.push(h), p.push(C);
|
|
176
344
|
}
|
|
177
345
|
else
|
|
178
|
-
|
|
346
|
+
f.push(h), p.push(C);
|
|
179
347
|
}
|
|
180
|
-
if (
|
|
181
|
-
const
|
|
182
|
-
if (
|
|
183
|
-
delete
|
|
184
|
-
const
|
|
185
|
-
|
|
348
|
+
if (w) {
|
|
349
|
+
const h = oe(r);
|
|
350
|
+
if (n[h] = f, rt(n, h, p), Ae(n, h), h !== r) {
|
|
351
|
+
delete n[r];
|
|
352
|
+
const C = H(r);
|
|
353
|
+
C !== r && delete n[C];
|
|
186
354
|
}
|
|
187
355
|
}
|
|
188
|
-
} else if (typeof
|
|
189
|
-
if (
|
|
190
|
-
const
|
|
191
|
-
if (
|
|
356
|
+
} else if (typeof a == "string") {
|
|
357
|
+
if (N.includes(a) || !$.has(a)) continue;
|
|
358
|
+
const c = $.get(a);
|
|
359
|
+
if (F.get(a) === J)
|
|
360
|
+
continue;
|
|
361
|
+
const d = c?.storageTransactionId ?? c?.storage_transaction_id;
|
|
362
|
+
if (d && typeof d == "string" && d.trim())
|
|
192
363
|
try {
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
364
|
+
const f = r.endsWith("_id") ? r.replace(/_id$/, "") : r;
|
|
365
|
+
n[f] = j(d);
|
|
366
|
+
const p = F.get(a) ?? "unknown";
|
|
367
|
+
fe(n, f, p);
|
|
368
|
+
const w = H(f);
|
|
369
|
+
if (w !== f && fe(n, w, p), f !== r) {
|
|
370
|
+
delete n[r];
|
|
371
|
+
const h = H(r);
|
|
372
|
+
h !== r && delete n[h];
|
|
198
373
|
}
|
|
199
374
|
} catch {
|
|
200
375
|
}
|
|
@@ -202,105 +377,143 @@ function je(a) {
|
|
|
202
377
|
}
|
|
203
378
|
}
|
|
204
379
|
}
|
|
205
|
-
function
|
|
206
|
-
if (!
|
|
207
|
-
const
|
|
208
|
-
([
|
|
380
|
+
function pt(t, e, n) {
|
|
381
|
+
if (!n) return;
|
|
382
|
+
const s = Array.from($.entries()).filter(
|
|
383
|
+
([r]) => F.get(r) === t
|
|
209
384
|
);
|
|
210
|
-
for (const [,
|
|
211
|
-
const
|
|
212
|
-
(
|
|
385
|
+
for (const [, r] of s) {
|
|
386
|
+
const a = Object.keys(r).filter(
|
|
387
|
+
(o) => !o.startsWith("_") && !ve.has(o)
|
|
213
388
|
);
|
|
214
|
-
for (const
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
389
|
+
for (const o of a) {
|
|
390
|
+
let i = r[o];
|
|
391
|
+
const c = Ie(i);
|
|
392
|
+
c !== i && Array.isArray(c) && (r[o] = c, i = c);
|
|
393
|
+
const d = Array.isArray(i), f = d ? i : [i], p = [];
|
|
394
|
+
let w = !1;
|
|
395
|
+
for (const h of f) {
|
|
396
|
+
if (typeof h != "string" || N.includes(h)) {
|
|
397
|
+
p.push(h);
|
|
398
|
+
continue;
|
|
399
|
+
}
|
|
400
|
+
const C = $.get(h);
|
|
401
|
+
if (!C) {
|
|
402
|
+
p.push(h);
|
|
220
403
|
continue;
|
|
221
404
|
}
|
|
222
|
-
const m =
|
|
223
|
-
if (
|
|
224
|
-
|
|
405
|
+
const m = C?.storageTransactionId ?? C?.storage_transaction_id;
|
|
406
|
+
if (F.get(h) === J) {
|
|
407
|
+
const g = F.get(h) ?? "unknown", D = { ...C };
|
|
408
|
+
ne(D, h, g, e), tt(D), p.push(D), w = !0;
|
|
225
409
|
continue;
|
|
226
410
|
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
f.push(g);
|
|
411
|
+
if (m && typeof m == "string" && m.trim()) {
|
|
412
|
+
p.push(h);
|
|
230
413
|
continue;
|
|
231
414
|
}
|
|
232
|
-
const
|
|
233
|
-
|
|
415
|
+
const l = F.get(h) ?? "unknown", u = { ...C };
|
|
416
|
+
ne(u, h, l, e), p.push(u), w = !0;
|
|
234
417
|
}
|
|
235
|
-
if (
|
|
236
|
-
const
|
|
237
|
-
if (
|
|
238
|
-
delete
|
|
239
|
-
const
|
|
240
|
-
|
|
418
|
+
if (w) {
|
|
419
|
+
const h = d ? oe(o) : o.endsWith("_id") ? o.replace(/_id$/, "") : o;
|
|
420
|
+
if (r[h] = d ? p : p[0], Ae(r, h), h !== o) {
|
|
421
|
+
delete r[o];
|
|
422
|
+
const C = H(o);
|
|
423
|
+
C !== o && delete r[C];
|
|
241
424
|
}
|
|
242
425
|
}
|
|
243
426
|
}
|
|
244
427
|
}
|
|
245
428
|
}
|
|
246
|
-
async function
|
|
247
|
-
|
|
248
|
-
const
|
|
249
|
-
where:
|
|
429
|
+
async function ke(t, e, n) {
|
|
430
|
+
ht(), await he(e);
|
|
431
|
+
const s = Te.getEasClient(), r = Array.from(Y), { itemSeeds: a } = await s.request(Ue, {
|
|
432
|
+
where: Se({
|
|
250
433
|
id: {
|
|
251
|
-
in:
|
|
434
|
+
in: r
|
|
252
435
|
}
|
|
253
436
|
}),
|
|
254
|
-
take:
|
|
437
|
+
take: r.length || 1,
|
|
255
438
|
skip: 0
|
|
256
439
|
});
|
|
257
|
-
await
|
|
258
|
-
const
|
|
259
|
-
itemUrlBase:
|
|
260
|
-
itemUrlPath:
|
|
261
|
-
siteUrl:
|
|
440
|
+
await he(a ?? []), gt(t);
|
|
441
|
+
const o = G(), i = {
|
|
442
|
+
itemUrlBase: o.itemUrlBase,
|
|
443
|
+
itemUrlPath: o.itemUrlPath,
|
|
444
|
+
siteUrl: o.siteUrl
|
|
262
445
|
};
|
|
263
|
-
|
|
264
|
-
|
|
446
|
+
pt(
|
|
447
|
+
t,
|
|
265
448
|
i,
|
|
266
|
-
|
|
267
|
-
)
|
|
268
|
-
|
|
269
|
-
|
|
449
|
+
n
|
|
450
|
+
);
|
|
451
|
+
const c = Array.from($.entries()).filter(([d]) => F.get(d) === t).map(([, d]) => {
|
|
452
|
+
const f = d.seedUid || d.SeedUid;
|
|
453
|
+
return ne(d, f, t, i), d;
|
|
270
454
|
});
|
|
455
|
+
return await it(c), c;
|
|
271
456
|
}
|
|
272
|
-
const
|
|
273
|
-
const
|
|
274
|
-
return
|
|
275
|
-
},
|
|
276
|
-
const
|
|
457
|
+
const te = async (t, e) => {
|
|
458
|
+
const n = G(), s = e?.limit ?? 100, r = e?.skip ?? 0, a = await We(t, s, r);
|
|
459
|
+
return ke(t, a, n.expandRelations !== !1);
|
|
460
|
+
}, mt = async (t, e, n) => {
|
|
461
|
+
const s = G(), r = new Date(e, n - 1, 1), a = new Date(e, n, 0, 23, 59, 59), o = Math.floor(r.getTime() / 1e3), i = Math.floor(a.getTime() / 1e3) + 1, c = Se({
|
|
277
462
|
AND: [
|
|
278
463
|
{
|
|
279
464
|
schema: {
|
|
280
465
|
is: {
|
|
281
466
|
schemaNames: {
|
|
282
467
|
some: {
|
|
283
|
-
name: { equals:
|
|
468
|
+
name: { equals: t }
|
|
284
469
|
}
|
|
285
470
|
}
|
|
286
471
|
}
|
|
287
472
|
}
|
|
288
473
|
},
|
|
289
474
|
{
|
|
290
|
-
timeCreated: { gte:
|
|
475
|
+
timeCreated: { gte: o, lt: i }
|
|
291
476
|
}
|
|
292
477
|
]
|
|
293
|
-
}), d =
|
|
294
|
-
where:
|
|
478
|
+
}), d = Te.getEasClient(), { itemSeeds: f } = await d.request(Ue, {
|
|
479
|
+
where: c,
|
|
295
480
|
take: 1e3,
|
|
296
481
|
skip: 0
|
|
297
482
|
});
|
|
298
|
-
return
|
|
299
|
-
}
|
|
300
|
-
function
|
|
301
|
-
|
|
483
|
+
return ke(t, f ?? [], s.expandRelations !== !1);
|
|
484
|
+
};
|
|
485
|
+
function yt(t) {
|
|
486
|
+
try {
|
|
487
|
+
return JSON.parse(JSON.stringify(t));
|
|
488
|
+
} catch {
|
|
489
|
+
return { ...t };
|
|
490
|
+
}
|
|
302
491
|
}
|
|
303
|
-
const
|
|
492
|
+
const wt = new Ye({
|
|
493
|
+
customFields: {
|
|
494
|
+
item: [
|
|
495
|
+
"featureImage",
|
|
496
|
+
"feature_image",
|
|
497
|
+
"content:encoded",
|
|
498
|
+
"seedUid",
|
|
499
|
+
"SeedUid"
|
|
500
|
+
]
|
|
501
|
+
}
|
|
502
|
+
});
|
|
503
|
+
async function Qt(t) {
|
|
504
|
+
const e = await wt.parseString(t);
|
|
505
|
+
return {
|
|
506
|
+
title: e.title,
|
|
507
|
+
link: e.link,
|
|
508
|
+
description: e.description,
|
|
509
|
+
items: (e.items ?? []).map(yt)
|
|
510
|
+
};
|
|
511
|
+
}
|
|
512
|
+
const z = "http://purl.org/dc/elements/1.1/", K = "http://purl.org/rss/1.0/modules/content/", x = "http://search.yahoo.com/mrss/", Ct = /* @__PURE__ */ new Set(["Title", "Link", "Guid", "PubDate", "SeedUid"]);
|
|
513
|
+
function Dt(t, e) {
|
|
514
|
+
return Ct.has(t) ? t.charAt(0).toLowerCase() + t.slice(1) in e : !1;
|
|
515
|
+
}
|
|
516
|
+
const ue = [
|
|
304
517
|
"title",
|
|
305
518
|
"link",
|
|
306
519
|
"description",
|
|
@@ -324,248 +537,270 @@ const ae = [
|
|
|
324
537
|
"media:category",
|
|
325
538
|
"media:group"
|
|
326
539
|
];
|
|
327
|
-
function
|
|
328
|
-
if (
|
|
329
|
-
return
|
|
330
|
-
if (typeof
|
|
331
|
-
const e = new Date(
|
|
332
|
-
return Number.isNaN(e.getTime()) ?
|
|
333
|
-
}
|
|
334
|
-
return String(
|
|
540
|
+
function re(t) {
|
|
541
|
+
if (t instanceof Date)
|
|
542
|
+
return t.toUTCString();
|
|
543
|
+
if (typeof t == "string") {
|
|
544
|
+
const e = new Date(t);
|
|
545
|
+
return Number.isNaN(e.getTime()) ? t : e.toUTCString();
|
|
546
|
+
}
|
|
547
|
+
return String(t);
|
|
335
548
|
}
|
|
336
|
-
function
|
|
337
|
-
return /[<>&]|]]>/.test(
|
|
549
|
+
function St(t) {
|
|
550
|
+
return /[<>&]|]]>/.test(t);
|
|
338
551
|
}
|
|
339
|
-
function _(
|
|
340
|
-
const
|
|
341
|
-
if (
|
|
342
|
-
if (
|
|
343
|
-
if (
|
|
344
|
-
const
|
|
345
|
-
for (let
|
|
346
|
-
|
|
552
|
+
function _(t, e) {
|
|
553
|
+
const n = String(e);
|
|
554
|
+
if (n !== "")
|
|
555
|
+
if (St(n))
|
|
556
|
+
if (n.includes("]]>")) {
|
|
557
|
+
const s = n.split("]]>");
|
|
558
|
+
for (let r = 0; r < s.length; r++)
|
|
559
|
+
t.dat(s[r]), r < s.length - 1 && t.txt("]]>");
|
|
347
560
|
} else
|
|
348
|
-
|
|
561
|
+
t.dat(n);
|
|
349
562
|
else
|
|
350
|
-
|
|
563
|
+
t.txt(n);
|
|
351
564
|
}
|
|
352
|
-
function
|
|
353
|
-
return
|
|
565
|
+
function P(t) {
|
|
566
|
+
return t !== null && typeof t == "object" && !Array.isArray(t) && !(t instanceof Date);
|
|
354
567
|
}
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
568
|
+
const Tt = 4;
|
|
569
|
+
function R(t, e, n, s, r = 0) {
|
|
570
|
+
const a = t.ele(n);
|
|
571
|
+
for (const [o, i] of Object.entries(e)) {
|
|
572
|
+
if (i == null || o.startsWith("_") || o === "items") continue;
|
|
573
|
+
if (r >= Tt) {
|
|
574
|
+
const d = a.ele(o);
|
|
575
|
+
_(d, typeof i == "object" ? JSON.stringify(i) : String(i));
|
|
576
|
+
continue;
|
|
577
|
+
}
|
|
578
|
+
if (Array.isArray(i)) {
|
|
579
|
+
const d = o.endsWith("s") && o.length > 1 ? o.slice(0, -1) : o;
|
|
580
|
+
for (const f of i)
|
|
581
|
+
if (f != null)
|
|
582
|
+
if (P(f))
|
|
583
|
+
R(a, f, d, !1, r + 1);
|
|
584
|
+
else {
|
|
585
|
+
const p = a.ele(d);
|
|
586
|
+
_(p, String(f));
|
|
587
|
+
}
|
|
588
|
+
continue;
|
|
589
|
+
}
|
|
590
|
+
if (P(i)) {
|
|
591
|
+
R(a, i, o, !1, r + 1);
|
|
592
|
+
continue;
|
|
593
|
+
}
|
|
594
|
+
const c = a.ele(o);
|
|
595
|
+
_(c, String(i));
|
|
361
596
|
}
|
|
362
|
-
if (
|
|
363
|
-
const
|
|
364
|
-
|
|
597
|
+
if (s) {
|
|
598
|
+
const o = e.name ?? e.seedUid;
|
|
599
|
+
o && t.ele(z, "creator").txt(String(o));
|
|
365
600
|
}
|
|
366
601
|
}
|
|
367
|
-
function
|
|
368
|
-
if (
|
|
602
|
+
function ge(t, e, n, s) {
|
|
603
|
+
if (n == null || e.startsWith("_") || e === "items") return;
|
|
369
604
|
if (e === "guid") {
|
|
370
|
-
const
|
|
371
|
-
if (!
|
|
605
|
+
const a = n, o = a?.value ?? String(n);
|
|
606
|
+
if (!o) return;
|
|
372
607
|
const i = {};
|
|
373
|
-
typeof
|
|
374
|
-
const
|
|
375
|
-
_(
|
|
608
|
+
typeof a?.isPermaLink == "boolean" && (i.isPermaLink = a.isPermaLink ? "true" : "false");
|
|
609
|
+
const c = t.ele("guid", i);
|
|
610
|
+
_(c, o);
|
|
376
611
|
return;
|
|
377
612
|
}
|
|
378
|
-
if (e === "source" &&
|
|
379
|
-
const
|
|
380
|
-
if (!
|
|
381
|
-
const i =
|
|
382
|
-
|
|
613
|
+
if (e === "source" && n !== null && typeof n == "object") {
|
|
614
|
+
const a = n, o = a.title ?? String(n);
|
|
615
|
+
if (!o) return;
|
|
616
|
+
const i = a.url ? { url: a.url } : {};
|
|
617
|
+
t.ele("source", i).txt(o);
|
|
383
618
|
return;
|
|
384
619
|
}
|
|
385
|
-
if (e === "enclosures" && Array.isArray(
|
|
386
|
-
for (const
|
|
387
|
-
if (
|
|
388
|
-
const
|
|
389
|
-
url: String(
|
|
390
|
-
type: String(
|
|
620
|
+
if (e === "enclosures" && Array.isArray(n)) {
|
|
621
|
+
for (const a of n)
|
|
622
|
+
if (a && typeof a == "object" && "url" in a) {
|
|
623
|
+
const o = {
|
|
624
|
+
url: String(a.url),
|
|
625
|
+
type: String(a.type ?? "application/octet-stream")
|
|
391
626
|
};
|
|
392
|
-
|
|
627
|
+
a.length != null && (o.length = String(a.length)), t.ele("enclosure", o);
|
|
393
628
|
}
|
|
394
629
|
return;
|
|
395
630
|
}
|
|
396
|
-
if (e === "dc" &&
|
|
397
|
-
const
|
|
398
|
-
for (const [
|
|
631
|
+
if (e === "dc" && n !== null && typeof n == "object") {
|
|
632
|
+
const a = n;
|
|
633
|
+
for (const [o, i] of Object.entries(a))
|
|
399
634
|
if (i != null)
|
|
400
635
|
if (Array.isArray(i)) {
|
|
401
|
-
for (const
|
|
402
|
-
if (
|
|
403
|
-
const d =
|
|
404
|
-
|
|
636
|
+
for (const c of i)
|
|
637
|
+
if (c != null) {
|
|
638
|
+
const d = t.ele(z, o);
|
|
639
|
+
c instanceof Date ? d.txt(c.toISOString()) : _(d, String(c));
|
|
405
640
|
}
|
|
406
641
|
} else {
|
|
407
|
-
const
|
|
408
|
-
i instanceof Date ?
|
|
642
|
+
const c = t.ele(z, o);
|
|
643
|
+
i instanceof Date ? c.txt(i.toISOString()) : _(c, String(i));
|
|
409
644
|
}
|
|
410
645
|
return;
|
|
411
646
|
}
|
|
412
647
|
if (e === "content:encoded") {
|
|
413
|
-
const
|
|
414
|
-
_(
|
|
648
|
+
const a = t.ele(K, "encoded");
|
|
649
|
+
_(a, String(n));
|
|
415
650
|
return;
|
|
416
651
|
}
|
|
417
|
-
if (e === "content" && typeof
|
|
418
|
-
const
|
|
419
|
-
_(
|
|
652
|
+
if (e === "content" && typeof n == "string" && !("content:encoded" in s)) {
|
|
653
|
+
const a = t.ele(K, "encoded");
|
|
654
|
+
_(a, String(n));
|
|
420
655
|
return;
|
|
421
656
|
}
|
|
422
657
|
if (e === "content") return;
|
|
423
|
-
if (e.startsWith("media:") && Array.isArray(
|
|
424
|
-
const
|
|
425
|
-
for (const
|
|
426
|
-
if (
|
|
658
|
+
if (e.startsWith("media:") && Array.isArray(n)) {
|
|
659
|
+
const a = e.slice(6);
|
|
660
|
+
for (const o of n) {
|
|
661
|
+
if (o === null || typeof o != "object") continue;
|
|
427
662
|
const i = {};
|
|
428
|
-
let
|
|
429
|
-
for (const [f, p] of Object.entries(
|
|
430
|
-
p != null && (f === "value" ?
|
|
431
|
-
const d =
|
|
432
|
-
|
|
663
|
+
let c = null;
|
|
664
|
+
for (const [f, p] of Object.entries(o))
|
|
665
|
+
p != null && (f === "value" ? c = String(p) : i[f] = String(p));
|
|
666
|
+
const d = t.ele(x, a, i);
|
|
667
|
+
c !== null && _(d, c);
|
|
433
668
|
}
|
|
434
669
|
return;
|
|
435
670
|
}
|
|
436
|
-
if (e.startsWith("media:") && typeof
|
|
437
|
-
const
|
|
438
|
-
_(
|
|
671
|
+
if (e.startsWith("media:") && typeof n == "string") {
|
|
672
|
+
const a = e.slice(6), o = t.ele(x, a);
|
|
673
|
+
_(o, n);
|
|
439
674
|
return;
|
|
440
675
|
}
|
|
441
|
-
if (e === "media:group" && Array.isArray(
|
|
442
|
-
for (const
|
|
443
|
-
if (
|
|
444
|
-
const
|
|
445
|
-
for (const [i,
|
|
446
|
-
if (
|
|
676
|
+
if (e === "media:group" && Array.isArray(n)) {
|
|
677
|
+
for (const a of n)
|
|
678
|
+
if (a && typeof a == "object") {
|
|
679
|
+
const o = t.ele(x, "group");
|
|
680
|
+
for (const [i, c] of Object.entries(a))
|
|
681
|
+
if (c != null && i.startsWith("media:")) {
|
|
447
682
|
const d = i.slice(6);
|
|
448
|
-
if (Array.isArray(
|
|
449
|
-
for (const f of
|
|
683
|
+
if (Array.isArray(c)) {
|
|
684
|
+
for (const f of c)
|
|
450
685
|
if (f && typeof f == "object") {
|
|
451
|
-
const p =
|
|
452
|
-
for (const [
|
|
453
|
-
|
|
686
|
+
const p = o.ele(x, d);
|
|
687
|
+
for (const [w, h] of Object.entries(f))
|
|
688
|
+
h != null && (w === "url" || w === "value" ? _(p, String(h)) : p.att(w, String(h)));
|
|
454
689
|
}
|
|
455
|
-
} else typeof
|
|
690
|
+
} else typeof c == "string" && _(o.ele(x, d), c);
|
|
456
691
|
}
|
|
457
692
|
}
|
|
458
693
|
return;
|
|
459
694
|
}
|
|
460
|
-
if (
|
|
461
|
-
|
|
695
|
+
if (n instanceof Date) {
|
|
696
|
+
t.ele(e).txt(re(n));
|
|
462
697
|
return;
|
|
463
698
|
}
|
|
464
|
-
if (e === "author" &&
|
|
465
|
-
|
|
699
|
+
if (e === "author" && P(n)) {
|
|
700
|
+
R(t, n, "author", !0);
|
|
466
701
|
return;
|
|
467
702
|
}
|
|
468
|
-
if (e === "authors" && Array.isArray(
|
|
469
|
-
for (const
|
|
470
|
-
if (
|
|
471
|
-
|
|
703
|
+
if (e === "authors" && Array.isArray(n)) {
|
|
704
|
+
for (const a of n)
|
|
705
|
+
if (a && P(a))
|
|
706
|
+
R(t, a, "author", !0);
|
|
472
707
|
else {
|
|
473
|
-
const
|
|
474
|
-
|
|
708
|
+
const o = typeof a == "string" ? a : a && typeof a == "object" && "name" in a ? `${a.email ?? ""} (${a.name ?? ""})`.trim() || a.name : String(a);
|
|
709
|
+
o && t.ele("author").txt(o);
|
|
475
710
|
}
|
|
476
711
|
return;
|
|
477
712
|
}
|
|
478
|
-
if (e === "categories" && Array.isArray(
|
|
479
|
-
for (const
|
|
480
|
-
const
|
|
481
|
-
if (
|
|
482
|
-
const i =
|
|
483
|
-
|
|
713
|
+
if (e === "categories" && Array.isArray(n)) {
|
|
714
|
+
for (const a of n) {
|
|
715
|
+
const o = a && typeof a == "object" && "name" in a ? a.name : String(a);
|
|
716
|
+
if (o) {
|
|
717
|
+
const i = a && typeof a == "object" && "domain" in a && a.domain ? { domain: a.domain } : {};
|
|
718
|
+
t.ele("category", i).txt(o);
|
|
484
719
|
}
|
|
485
720
|
}
|
|
486
721
|
return;
|
|
487
722
|
}
|
|
488
|
-
if (Array.isArray(
|
|
489
|
-
const
|
|
490
|
-
for (const
|
|
491
|
-
|
|
723
|
+
if (Array.isArray(n) && n.length > 0 && n.every((a) => P(a))) {
|
|
724
|
+
const a = e.endsWith("s") ? e.slice(0, -1) : e;
|
|
725
|
+
for (const o of n)
|
|
726
|
+
o && R(t, o, a, !1);
|
|
492
727
|
return;
|
|
493
728
|
}
|
|
494
|
-
if (Array.isArray(
|
|
495
|
-
const
|
|
496
|
-
for (const
|
|
497
|
-
if (
|
|
498
|
-
const i =
|
|
499
|
-
_(i,
|
|
729
|
+
if (Array.isArray(n) && n.every((a) => typeof a == "string")) {
|
|
730
|
+
const a = e.endsWith("s") ? e.slice(0, -1) : e;
|
|
731
|
+
for (const o of n)
|
|
732
|
+
if (o) {
|
|
733
|
+
const i = t.ele(a);
|
|
734
|
+
_(i, o);
|
|
500
735
|
}
|
|
501
736
|
return;
|
|
502
737
|
}
|
|
503
|
-
if (
|
|
504
|
-
|
|
738
|
+
if (P(n)) {
|
|
739
|
+
R(t, n, e, !1);
|
|
505
740
|
return;
|
|
506
741
|
}
|
|
507
|
-
const
|
|
508
|
-
_(
|
|
742
|
+
const r = t.ele(e);
|
|
743
|
+
_(r, String(n));
|
|
509
744
|
}
|
|
510
|
-
const
|
|
511
|
-
function
|
|
512
|
-
const e =
|
|
513
|
-
"xmlns:dc":
|
|
514
|
-
"xmlns:content":
|
|
515
|
-
"xmlns:media":
|
|
516
|
-
"xmlns:atom":
|
|
745
|
+
const pe = "http://www.w3.org/2005/Atom", me = "http://purl.org/syndication/history/1.0";
|
|
746
|
+
function Et(t) {
|
|
747
|
+
const e = Ze({ version: "1.0", encoding: "UTF-8" }), n = {
|
|
748
|
+
"xmlns:dc": z,
|
|
749
|
+
"xmlns:content": K,
|
|
750
|
+
"xmlns:media": x,
|
|
751
|
+
"xmlns:atom": pe
|
|
517
752
|
};
|
|
518
|
-
|
|
519
|
-
const
|
|
520
|
-
"xmlns:dc":
|
|
521
|
-
"xmlns:content":
|
|
522
|
-
"xmlns:media":
|
|
753
|
+
t.isArchive && (n["xmlns:fh"] = me);
|
|
754
|
+
const r = e.ele("rss", { version: "2.0", ...n }).ele("channel", {
|
|
755
|
+
"xmlns:dc": z,
|
|
756
|
+
"xmlns:content": K,
|
|
757
|
+
"xmlns:media": x
|
|
523
758
|
});
|
|
524
|
-
if (
|
|
525
|
-
for (const
|
|
526
|
-
const i = { rel:
|
|
527
|
-
|
|
759
|
+
if (r.ele("title").txt(t.title), t.link && r.ele("link").txt(t.link), r.ele("description").txt(t.description), t.language && r.ele("language").txt(t.language), t.copyright && r.ele("copyright").txt(t.copyright), t.webMaster && r.ele("webMaster").txt(t.webMaster), t.pubDate && r.ele("pubDate").txt(re(t.pubDate)), t.lastBuildDate && r.ele("lastBuildDate").txt(re(t.lastBuildDate)), t.links?.length)
|
|
760
|
+
for (const o of t.links) {
|
|
761
|
+
const i = { rel: o.rel, href: o.href };
|
|
762
|
+
o.type && (i.type = o.type), r.ele(pe, "link", i);
|
|
528
763
|
}
|
|
529
|
-
|
|
530
|
-
const
|
|
531
|
-
for (const
|
|
532
|
-
const i =
|
|
533
|
-
for (const f of
|
|
534
|
-
f in
|
|
535
|
-
const d = Object.keys(
|
|
536
|
-
(f) => !
|
|
764
|
+
t.isArchive && r.ele(me, "archive");
|
|
765
|
+
const a = new Set(ue);
|
|
766
|
+
for (const o of t.items) {
|
|
767
|
+
const i = r.ele("item"), c = /* @__PURE__ */ new Set();
|
|
768
|
+
for (const f of ue)
|
|
769
|
+
f in o && (ge(i, f, o[f], o), c.add(f));
|
|
770
|
+
const d = Object.keys(o).filter(
|
|
771
|
+
(f) => !c.has(f) && !a.has(f) && !f.startsWith("_") && !Dt(f, o)
|
|
537
772
|
).sort();
|
|
538
773
|
for (const f of d)
|
|
539
|
-
|
|
774
|
+
ge(i, f, o[f], o);
|
|
540
775
|
}
|
|
541
776
|
return e.end({ prettyPrint: !0 });
|
|
542
777
|
}
|
|
543
|
-
function
|
|
544
|
-
return
|
|
778
|
+
function ae(t, e, n) {
|
|
779
|
+
return n?.archive ? `${t}:${e}:archive-${n.archive.year}-${n.archive.month}` : n?.page != null && n.page > 1 ? `${t}:${e}:page-${n.page}` : `${t}:${e}`;
|
|
545
780
|
}
|
|
546
|
-
function
|
|
547
|
-
return `"${
|
|
781
|
+
function xe(t) {
|
|
782
|
+
return `"${Qe("md5").update(t).digest("hex").substring(0, 16)}"`;
|
|
548
783
|
}
|
|
549
|
-
function
|
|
550
|
-
const
|
|
551
|
-
return
|
|
784
|
+
function At(t, e, n, s) {
|
|
785
|
+
const r = `${t}-${e}-${n}-${s}`;
|
|
786
|
+
return xe(r);
|
|
552
787
|
}
|
|
553
|
-
function
|
|
554
|
-
const
|
|
555
|
-
return
|
|
788
|
+
function It(t, e, n, s) {
|
|
789
|
+
const r = `${t}-${e}-${n}-${s}`;
|
|
790
|
+
return xe(r);
|
|
556
791
|
}
|
|
557
|
-
function
|
|
558
|
-
const
|
|
559
|
-
return t
|
|
792
|
+
function _t(t, e) {
|
|
793
|
+
const n = (s) => s.replace(/^"|"$/g, "");
|
|
794
|
+
return n(t) === n(e);
|
|
560
795
|
}
|
|
561
|
-
function
|
|
562
|
-
return
|
|
796
|
+
function $t(t) {
|
|
797
|
+
return t ? t.split(",").map((e) => e.trim()).filter((e) => e.length > 0) : [];
|
|
563
798
|
}
|
|
564
|
-
function
|
|
565
|
-
const
|
|
566
|
-
return
|
|
799
|
+
function Le(t, e) {
|
|
800
|
+
const n = $t(t);
|
|
801
|
+
return n.length === 0 ? !1 : n.includes("*") ? !0 : n.some((s) => _t(s, e));
|
|
567
802
|
}
|
|
568
|
-
class
|
|
803
|
+
class Mt {
|
|
569
804
|
feedDataCache = /* @__PURE__ */ new Map();
|
|
570
805
|
feedContentCache = /* @__PURE__ */ new Map();
|
|
571
806
|
imageMetadataCache = /* @__PURE__ */ new Map();
|
|
@@ -578,49 +813,49 @@ class Ye {
|
|
|
578
813
|
* Get cached feed data for a schema
|
|
579
814
|
*/
|
|
580
815
|
getFeedData(e) {
|
|
581
|
-
const
|
|
582
|
-
return
|
|
816
|
+
const n = this.feedDataCache.get(e);
|
|
817
|
+
return n ? Math.floor(Date.now() / 1e3) - n.lastUpdated > this.config.ttl ? (this.feedDataCache.delete(e), this.clearContentCache(e), null) : n : null;
|
|
583
818
|
}
|
|
584
819
|
/**
|
|
585
820
|
* Set cached feed data for a schema
|
|
586
821
|
*/
|
|
587
|
-
setFeedData(e,
|
|
588
|
-
const
|
|
589
|
-
let
|
|
590
|
-
for (const
|
|
591
|
-
const d =
|
|
592
|
-
d && d >
|
|
822
|
+
setFeedData(e, n) {
|
|
823
|
+
const s = Math.floor(Date.now() / 1e3);
|
|
824
|
+
let r = 0, a = "";
|
|
825
|
+
for (const c of n) {
|
|
826
|
+
const d = c.timeCreated;
|
|
827
|
+
d && d > r && (r = d, a = c.id || c.seedUid || c.SeedUid || "");
|
|
593
828
|
}
|
|
594
|
-
|
|
595
|
-
const
|
|
596
|
-
items: [...
|
|
829
|
+
r === 0 && (r = s);
|
|
830
|
+
const o = At(e, "data", r, n.length), i = {
|
|
831
|
+
items: [...n],
|
|
597
832
|
// Create a copy
|
|
598
|
-
lastProcessedTimestamp:
|
|
599
|
-
lastProcessedItemId:
|
|
600
|
-
lastUpdated:
|
|
601
|
-
etag:
|
|
833
|
+
lastProcessedTimestamp: r,
|
|
834
|
+
lastProcessedItemId: a,
|
|
835
|
+
lastUpdated: s,
|
|
836
|
+
etag: o
|
|
602
837
|
};
|
|
603
838
|
this.feedDataCache.set(e, i);
|
|
604
839
|
}
|
|
605
840
|
/**
|
|
606
841
|
* Get cached feed content for a schema and format
|
|
607
842
|
*/
|
|
608
|
-
getFeedContent(e,
|
|
609
|
-
const
|
|
610
|
-
return
|
|
843
|
+
getFeedContent(e, n, s) {
|
|
844
|
+
const r = ae(e, n, s), a = this.feedContentCache.get(r);
|
|
845
|
+
return a ? Math.floor(Date.now() / 1e3) > a.expiresAt ? (this.feedContentCache.delete(r), null) : a : null;
|
|
611
846
|
}
|
|
612
847
|
/**
|
|
613
848
|
* Set cached feed content for a schema and format
|
|
614
849
|
*/
|
|
615
|
-
setFeedContent(e,
|
|
616
|
-
const i =
|
|
617
|
-
content:
|
|
618
|
-
contentType:
|
|
850
|
+
setFeedContent(e, n, s, r, a, o) {
|
|
851
|
+
const i = ae(e, n, a), c = Math.floor(Date.now() / 1e3), d = o ?? this.config.ttl, f = c + d, p = It(e, n, c, s.length), w = {
|
|
852
|
+
content: s,
|
|
853
|
+
contentType: r,
|
|
619
854
|
etag: p,
|
|
620
|
-
lastModified:
|
|
855
|
+
lastModified: c,
|
|
621
856
|
expiresAt: f
|
|
622
857
|
};
|
|
623
|
-
this.feedContentCache.set(i,
|
|
858
|
+
this.feedContentCache.set(i, w);
|
|
624
859
|
}
|
|
625
860
|
/**
|
|
626
861
|
* Clear feed data cache for a schema
|
|
@@ -632,28 +867,28 @@ class Ye {
|
|
|
632
867
|
* Clear content cache for a schema (all formats)
|
|
633
868
|
*/
|
|
634
869
|
clearContentCache(e) {
|
|
635
|
-
const
|
|
636
|
-
for (const
|
|
637
|
-
|
|
638
|
-
|
|
870
|
+
const n = [];
|
|
871
|
+
for (const s of this.feedContentCache.keys())
|
|
872
|
+
s.startsWith(`${e}:`) && n.push(s);
|
|
873
|
+
n.forEach((s) => this.feedContentCache.delete(s));
|
|
639
874
|
}
|
|
640
875
|
/**
|
|
641
876
|
* Get cached image metadata for a transaction ID
|
|
642
877
|
*/
|
|
643
878
|
getImageMetadata(e) {
|
|
644
|
-
const
|
|
645
|
-
return
|
|
879
|
+
const n = this.imageMetadataCache.get(e);
|
|
880
|
+
return n ? Math.floor(Date.now() / 1e3) > n.expiresAt ? (this.imageMetadataCache.delete(e), null) : n.metadata : null;
|
|
646
881
|
}
|
|
647
882
|
/**
|
|
648
883
|
* Set cached image metadata for a transaction ID
|
|
649
884
|
*/
|
|
650
|
-
setImageMetadata(e,
|
|
651
|
-
const
|
|
652
|
-
metadata:
|
|
653
|
-
cachedAt:
|
|
654
|
-
expiresAt:
|
|
885
|
+
setImageMetadata(e, n) {
|
|
886
|
+
const s = Math.floor(Date.now() / 1e3), r = this.config.imageMetadata?.ttl || 604800, a = s + r, o = {
|
|
887
|
+
metadata: n,
|
|
888
|
+
cachedAt: s,
|
|
889
|
+
expiresAt: a
|
|
655
890
|
};
|
|
656
|
-
this.imageMetadataCache.set(e,
|
|
891
|
+
this.imageMetadataCache.set(e, o);
|
|
657
892
|
}
|
|
658
893
|
/**
|
|
659
894
|
* Clear all caches
|
|
@@ -665,17 +900,17 @@ class Ye {
|
|
|
665
900
|
* Get or create a refresh lock for a schema
|
|
666
901
|
* Prevents concurrent fetches for the same schema
|
|
667
902
|
*/
|
|
668
|
-
async withRefreshLock(e,
|
|
669
|
-
const
|
|
670
|
-
|
|
671
|
-
const
|
|
903
|
+
async withRefreshLock(e, n) {
|
|
904
|
+
const s = this.refreshLocks.get(e);
|
|
905
|
+
s && (await s, this.getFeedData(e));
|
|
906
|
+
const r = (async () => {
|
|
672
907
|
try {
|
|
673
|
-
return await
|
|
908
|
+
return await n();
|
|
674
909
|
} finally {
|
|
675
910
|
this.refreshLocks.delete(e);
|
|
676
911
|
}
|
|
677
912
|
})();
|
|
678
|
-
return this.refreshLocks.set(e,
|
|
913
|
+
return this.refreshLocks.set(e, r), r;
|
|
679
914
|
}
|
|
680
915
|
/**
|
|
681
916
|
* Update configuration
|
|
@@ -695,12 +930,12 @@ class Ye {
|
|
|
695
930
|
};
|
|
696
931
|
}
|
|
697
932
|
}
|
|
698
|
-
class
|
|
933
|
+
class Ft {
|
|
699
934
|
cacheDir;
|
|
700
935
|
config;
|
|
701
936
|
constructor(e) {
|
|
702
|
-
this.cacheDir = e.cacheDir, this.config = e, this.ensureCacheDir().catch((
|
|
703
|
-
console.error("Failed to create cache directory:",
|
|
937
|
+
this.cacheDir = e.cacheDir, this.config = e, this.ensureCacheDir().catch((n) => {
|
|
938
|
+
console.error("Failed to create cache directory:", n);
|
|
704
939
|
});
|
|
705
940
|
}
|
|
706
941
|
/**
|
|
@@ -708,7 +943,7 @@ class Ke {
|
|
|
708
943
|
*/
|
|
709
944
|
async ensureCacheDir() {
|
|
710
945
|
try {
|
|
711
|
-
await
|
|
946
|
+
await I.mkdir(this.cacheDir, { recursive: !0 });
|
|
712
947
|
} catch (e) {
|
|
713
948
|
if (e.code !== "EEXIST")
|
|
714
949
|
throw e;
|
|
@@ -723,16 +958,16 @@ class Ke {
|
|
|
723
958
|
/**
|
|
724
959
|
* Get file path for feed content
|
|
725
960
|
*/
|
|
726
|
-
getFeedContentPath(e,
|
|
727
|
-
const
|
|
728
|
-
return U(this.cacheDir, `${
|
|
961
|
+
getFeedContentPath(e, n, s) {
|
|
962
|
+
const a = ae(e, n, s).replace(/:/g, "-");
|
|
963
|
+
return U(this.cacheDir, `${a}.json`);
|
|
729
964
|
}
|
|
730
965
|
/**
|
|
731
966
|
* Get file path for image metadata
|
|
732
967
|
*/
|
|
733
968
|
getImageMetadataPath(e) {
|
|
734
|
-
const
|
|
735
|
-
return U(
|
|
969
|
+
const n = U(this.cacheDir, "image-metadata");
|
|
970
|
+
return U(n, `${e}.json`);
|
|
736
971
|
}
|
|
737
972
|
/**
|
|
738
973
|
* Ensure image metadata directory exists
|
|
@@ -740,7 +975,7 @@ class Ke {
|
|
|
740
975
|
async ensureImageMetadataDir() {
|
|
741
976
|
try {
|
|
742
977
|
const e = U(this.cacheDir, "image-metadata");
|
|
743
|
-
await
|
|
978
|
+
await I.mkdir(e, { recursive: !0 });
|
|
744
979
|
} catch (e) {
|
|
745
980
|
if (e.code !== "EEXIST")
|
|
746
981
|
throw e;
|
|
@@ -751,50 +986,50 @@ class Ke {
|
|
|
751
986
|
*/
|
|
752
987
|
async getFeedData(e) {
|
|
753
988
|
try {
|
|
754
|
-
const
|
|
755
|
-
return Math.floor(Date.now() / 1e3) -
|
|
756
|
-
} catch (
|
|
757
|
-
return
|
|
989
|
+
const n = this.getFeedDataPath(e), s = await I.readFile(n, "utf-8"), r = JSON.parse(s);
|
|
990
|
+
return Math.floor(Date.now() / 1e3) - r.lastUpdated > this.config.ttl ? (await this.clearFeedData(e), null) : r;
|
|
991
|
+
} catch (n) {
|
|
992
|
+
return n.code === "ENOENT" || console.error(`Error reading feed data cache for ${e}:`, n), null;
|
|
758
993
|
}
|
|
759
994
|
}
|
|
760
995
|
/**
|
|
761
996
|
* Set cached feed data for a schema
|
|
762
997
|
*/
|
|
763
|
-
async setFeedData(e,
|
|
998
|
+
async setFeedData(e, n) {
|
|
764
999
|
try {
|
|
765
1000
|
await this.ensureCacheDir();
|
|
766
|
-
const
|
|
767
|
-
await
|
|
768
|
-
} catch (
|
|
769
|
-
console.error(`Error writing feed data cache for ${e}:`,
|
|
1001
|
+
const s = this.getFeedDataPath(e);
|
|
1002
|
+
await I.writeFile(s, JSON.stringify(n, null, 2), "utf-8");
|
|
1003
|
+
} catch (s) {
|
|
1004
|
+
console.error(`Error writing feed data cache for ${e}:`, s);
|
|
770
1005
|
}
|
|
771
1006
|
}
|
|
772
1007
|
/**
|
|
773
1008
|
* Get cached feed content for a schema and format
|
|
774
1009
|
*/
|
|
775
|
-
async getFeedContent(e,
|
|
1010
|
+
async getFeedContent(e, n, s) {
|
|
776
1011
|
try {
|
|
777
|
-
const
|
|
778
|
-
return Math.floor(Date.now() / 1e3) >
|
|
779
|
-
} catch (
|
|
780
|
-
return
|
|
781
|
-
`Error reading feed content cache for ${e}:${
|
|
782
|
-
|
|
1012
|
+
const r = this.getFeedContentPath(e, n, s), a = await I.readFile(r, "utf-8"), o = JSON.parse(a);
|
|
1013
|
+
return Math.floor(Date.now() / 1e3) > o.expiresAt ? (await this.clearFeedContent(e, n, s), null) : o;
|
|
1014
|
+
} catch (r) {
|
|
1015
|
+
return r.code === "ENOENT" || console.error(
|
|
1016
|
+
`Error reading feed content cache for ${e}:${n}:`,
|
|
1017
|
+
r
|
|
783
1018
|
), null;
|
|
784
1019
|
}
|
|
785
1020
|
}
|
|
786
1021
|
/**
|
|
787
1022
|
* Set cached feed content for a schema and format
|
|
788
1023
|
*/
|
|
789
|
-
async setFeedContent(e,
|
|
1024
|
+
async setFeedContent(e, n, s, r) {
|
|
790
1025
|
try {
|
|
791
1026
|
await this.ensureCacheDir();
|
|
792
|
-
const
|
|
793
|
-
await
|
|
794
|
-
} catch (
|
|
1027
|
+
const a = this.getFeedContentPath(e, n, r);
|
|
1028
|
+
await I.writeFile(a, JSON.stringify(s, null, 2), "utf-8");
|
|
1029
|
+
} catch (a) {
|
|
795
1030
|
console.error(
|
|
796
|
-
`Error writing feed content cache for ${e}:${
|
|
797
|
-
|
|
1031
|
+
`Error writing feed content cache for ${e}:${n}:`,
|
|
1032
|
+
a
|
|
798
1033
|
);
|
|
799
1034
|
}
|
|
800
1035
|
}
|
|
@@ -803,23 +1038,23 @@ class Ke {
|
|
|
803
1038
|
*/
|
|
804
1039
|
async clearFeedData(e) {
|
|
805
1040
|
try {
|
|
806
|
-
const
|
|
807
|
-
await
|
|
808
|
-
} catch (
|
|
809
|
-
|
|
1041
|
+
const n = this.getFeedDataPath(e);
|
|
1042
|
+
await I.unlink(n);
|
|
1043
|
+
} catch (n) {
|
|
1044
|
+
n.code !== "ENOENT" && console.error(`Error clearing feed data cache for ${e}:`, n);
|
|
810
1045
|
}
|
|
811
1046
|
}
|
|
812
1047
|
/**
|
|
813
1048
|
* Clear content cache for a schema and format
|
|
814
1049
|
*/
|
|
815
|
-
async clearFeedContent(e,
|
|
1050
|
+
async clearFeedContent(e, n, s) {
|
|
816
1051
|
try {
|
|
817
|
-
const
|
|
818
|
-
await
|
|
819
|
-
} catch (
|
|
820
|
-
|
|
821
|
-
`Error clearing feed content cache for ${e}:${
|
|
822
|
-
|
|
1052
|
+
const r = this.getFeedContentPath(e, n, s);
|
|
1053
|
+
await I.unlink(r);
|
|
1054
|
+
} catch (r) {
|
|
1055
|
+
r.code !== "ENOENT" && console.error(
|
|
1056
|
+
`Error clearing feed content cache for ${e}:${n}:`,
|
|
1057
|
+
r
|
|
823
1058
|
);
|
|
824
1059
|
}
|
|
825
1060
|
}
|
|
@@ -828,11 +1063,11 @@ class Ke {
|
|
|
828
1063
|
*/
|
|
829
1064
|
async clearAllContentCache(e) {
|
|
830
1065
|
try {
|
|
831
|
-
const
|
|
832
|
-
for (const
|
|
833
|
-
|
|
834
|
-
} catch (
|
|
835
|
-
console.error(`Error clearing all content cache for ${e}:`,
|
|
1066
|
+
const n = await I.readdir(this.cacheDir), s = `${e}-`, r = ".json";
|
|
1067
|
+
for (const a of n)
|
|
1068
|
+
a.startsWith(s) && a.endsWith(r) && a !== `${e}.json` && await I.unlink(U(this.cacheDir, a));
|
|
1069
|
+
} catch (n) {
|
|
1070
|
+
console.error(`Error clearing all content cache for ${e}:`, n);
|
|
836
1071
|
}
|
|
837
1072
|
}
|
|
838
1073
|
/**
|
|
@@ -840,26 +1075,26 @@ class Ke {
|
|
|
840
1075
|
*/
|
|
841
1076
|
async getImageMetadata(e) {
|
|
842
1077
|
try {
|
|
843
|
-
const
|
|
844
|
-
return Math.floor(Date.now() / 1e3) >
|
|
845
|
-
} catch (
|
|
846
|
-
return
|
|
1078
|
+
const n = this.getImageMetadataPath(e), s = await I.readFile(n, "utf-8"), r = JSON.parse(s);
|
|
1079
|
+
return Math.floor(Date.now() / 1e3) > r.expiresAt ? (await this.clearImageMetadata(e), null) : r.metadata;
|
|
1080
|
+
} catch (n) {
|
|
1081
|
+
return n.code === "ENOENT" || console.error(`Error reading image metadata cache for ${e}:`, n), null;
|
|
847
1082
|
}
|
|
848
1083
|
}
|
|
849
1084
|
/**
|
|
850
1085
|
* Set cached image metadata for a transaction ID
|
|
851
1086
|
*/
|
|
852
|
-
async setImageMetadata(e,
|
|
1087
|
+
async setImageMetadata(e, n) {
|
|
853
1088
|
try {
|
|
854
1089
|
await this.ensureImageMetadataDir();
|
|
855
|
-
const
|
|
856
|
-
metadata:
|
|
857
|
-
cachedAt:
|
|
858
|
-
expiresAt:
|
|
1090
|
+
const s = this.getImageMetadataPath(e), r = Math.floor(Date.now() / 1e3), a = this.config.imageMetadata?.ttl || 604800, o = r + a, i = {
|
|
1091
|
+
metadata: n,
|
|
1092
|
+
cachedAt: r,
|
|
1093
|
+
expiresAt: o
|
|
859
1094
|
};
|
|
860
|
-
await
|
|
861
|
-
} catch (
|
|
862
|
-
console.error(`Error writing image metadata cache for ${e}:`,
|
|
1095
|
+
await I.writeFile(s, JSON.stringify(i, null, 2), "utf-8");
|
|
1096
|
+
} catch (s) {
|
|
1097
|
+
console.error(`Error writing image metadata cache for ${e}:`, s);
|
|
863
1098
|
}
|
|
864
1099
|
}
|
|
865
1100
|
/**
|
|
@@ -867,10 +1102,10 @@ class Ke {
|
|
|
867
1102
|
*/
|
|
868
1103
|
async clearImageMetadata(e) {
|
|
869
1104
|
try {
|
|
870
|
-
const
|
|
871
|
-
await
|
|
872
|
-
} catch (
|
|
873
|
-
|
|
1105
|
+
const n = this.getImageMetadataPath(e);
|
|
1106
|
+
await I.unlink(n);
|
|
1107
|
+
} catch (n) {
|
|
1108
|
+
n.code !== "ENOENT" && console.error(`Error clearing image metadata cache for ${e}:`, n);
|
|
874
1109
|
}
|
|
875
1110
|
}
|
|
876
1111
|
/**
|
|
@@ -878,14 +1113,14 @@ class Ke {
|
|
|
878
1113
|
*/
|
|
879
1114
|
async clearAll() {
|
|
880
1115
|
try {
|
|
881
|
-
const e = await
|
|
882
|
-
for (const
|
|
883
|
-
|
|
884
|
-
const
|
|
1116
|
+
const e = await I.readdir(this.cacheDir);
|
|
1117
|
+
for (const s of e)
|
|
1118
|
+
s.endsWith(".json") && await I.unlink(U(this.cacheDir, s));
|
|
1119
|
+
const n = U(this.cacheDir, "image-metadata");
|
|
885
1120
|
try {
|
|
886
|
-
const
|
|
887
|
-
for (const
|
|
888
|
-
|
|
1121
|
+
const s = await I.readdir(n);
|
|
1122
|
+
for (const r of s)
|
|
1123
|
+
r.endsWith(".json") && await I.unlink(U(n, r));
|
|
889
1124
|
} catch {
|
|
890
1125
|
}
|
|
891
1126
|
} catch (e) {
|
|
@@ -893,7 +1128,7 @@ class Ke {
|
|
|
893
1128
|
}
|
|
894
1129
|
}
|
|
895
1130
|
}
|
|
896
|
-
class
|
|
1131
|
+
class Ut {
|
|
897
1132
|
memoryCache;
|
|
898
1133
|
fileCache;
|
|
899
1134
|
config;
|
|
@@ -904,7 +1139,7 @@ class Ze {
|
|
|
904
1139
|
errors: 0
|
|
905
1140
|
};
|
|
906
1141
|
constructor(e) {
|
|
907
|
-
this.config = e, this.memoryCache = new
|
|
1142
|
+
this.config = e, this.memoryCache = new Mt(e), this.fileCache = new Ft(e);
|
|
908
1143
|
}
|
|
909
1144
|
/**
|
|
910
1145
|
* Get cached feed data for a schema
|
|
@@ -914,46 +1149,46 @@ class Ze {
|
|
|
914
1149
|
if (!this.config.enabled)
|
|
915
1150
|
return null;
|
|
916
1151
|
try {
|
|
917
|
-
let
|
|
918
|
-
return
|
|
919
|
-
} catch (
|
|
920
|
-
return console.error(`Error getting feed data cache for ${e}:`,
|
|
1152
|
+
let n = this.memoryCache.getFeedData(e);
|
|
1153
|
+
return n ? (this.stats.hits++, n) : (n = await this.fileCache.getFeedData(e), n ? (this.memoryCache.setFeedData(e, n.items), this.stats.hits++, n) : (this.stats.misses++, null));
|
|
1154
|
+
} catch (n) {
|
|
1155
|
+
return console.error(`Error getting feed data cache for ${e}:`, n), this.stats.errors++, null;
|
|
921
1156
|
}
|
|
922
1157
|
}
|
|
923
1158
|
/**
|
|
924
1159
|
* Set cached feed data for a schema
|
|
925
1160
|
* Updates both memory and file cache
|
|
926
1161
|
*/
|
|
927
|
-
async setFeedData(e,
|
|
1162
|
+
async setFeedData(e, n) {
|
|
928
1163
|
if (this.config.enabled)
|
|
929
1164
|
try {
|
|
930
|
-
this.memoryCache.setFeedData(e,
|
|
931
|
-
const
|
|
932
|
-
|
|
933
|
-
} catch (
|
|
934
|
-
console.error(`Error setting feed data cache for ${e}:`,
|
|
1165
|
+
this.memoryCache.setFeedData(e, n);
|
|
1166
|
+
const s = this.memoryCache.getFeedData(e);
|
|
1167
|
+
s && await this.fileCache.setFeedData(e, s);
|
|
1168
|
+
} catch (s) {
|
|
1169
|
+
console.error(`Error setting feed data cache for ${e}:`, s), this.stats.errors++;
|
|
935
1170
|
}
|
|
936
1171
|
}
|
|
937
1172
|
/**
|
|
938
1173
|
* Get cached feed content for a schema and format
|
|
939
1174
|
* Checks memory cache first, then file cache
|
|
940
1175
|
*/
|
|
941
|
-
async getFeedContent(e,
|
|
1176
|
+
async getFeedContent(e, n, s) {
|
|
942
1177
|
if (!this.config.enabled)
|
|
943
1178
|
return null;
|
|
944
1179
|
try {
|
|
945
|
-
let
|
|
946
|
-
return
|
|
1180
|
+
let r = this.memoryCache.getFeedContent(e, n, s);
|
|
1181
|
+
return r ? (this.stats.hits++, r) : (r = await this.fileCache.getFeedContent(e, n, s), r ? (this.memoryCache.setFeedContent(
|
|
947
1182
|
e,
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
o
|
|
952
|
-
), this.stats.hits++, s) : (this.stats.misses++, null));
|
|
953
|
-
} catch (s) {
|
|
954
|
-
return console.error(
|
|
955
|
-
`Error getting feed content cache for ${e}:${t}:`,
|
|
1183
|
+
n,
|
|
1184
|
+
r.content,
|
|
1185
|
+
r.contentType,
|
|
956
1186
|
s
|
|
1187
|
+
), this.stats.hits++, r) : (this.stats.misses++, null));
|
|
1188
|
+
} catch (r) {
|
|
1189
|
+
return console.error(
|
|
1190
|
+
`Error getting feed content cache for ${e}:${n}:`,
|
|
1191
|
+
r
|
|
957
1192
|
), this.stats.errors++, null;
|
|
958
1193
|
}
|
|
959
1194
|
}
|
|
@@ -961,24 +1196,24 @@ class Ze {
|
|
|
961
1196
|
* Set cached feed content for a schema and format
|
|
962
1197
|
* Updates both memory and file cache
|
|
963
1198
|
*/
|
|
964
|
-
async setFeedContent(e,
|
|
1199
|
+
async setFeedContent(e, n, s, r, a) {
|
|
965
1200
|
if (this.config.enabled)
|
|
966
1201
|
try {
|
|
967
|
-
let
|
|
968
|
-
|
|
1202
|
+
let o;
|
|
1203
|
+
a?.archive ? o = this.config.archiveTtl ?? 86400 : a?.page != null && a.page > 1 && (o = this.config.pageTtl ?? 300), this.memoryCache.setFeedContent(
|
|
969
1204
|
e,
|
|
970
|
-
|
|
971
|
-
o,
|
|
1205
|
+
n,
|
|
972
1206
|
s,
|
|
973
1207
|
r,
|
|
974
|
-
|
|
1208
|
+
a,
|
|
1209
|
+
o
|
|
975
1210
|
);
|
|
976
|
-
const i = this.memoryCache.getFeedContent(e,
|
|
977
|
-
i && await this.fileCache.setFeedContent(e,
|
|
978
|
-
} catch (
|
|
1211
|
+
const i = this.memoryCache.getFeedContent(e, n, a);
|
|
1212
|
+
i && await this.fileCache.setFeedContent(e, n, i, a);
|
|
1213
|
+
} catch (o) {
|
|
979
1214
|
console.error(
|
|
980
|
-
`Error setting feed content cache for ${e}:${
|
|
981
|
-
|
|
1215
|
+
`Error setting feed content cache for ${e}:${n}:`,
|
|
1216
|
+
o
|
|
982
1217
|
), this.stats.errors++;
|
|
983
1218
|
}
|
|
984
1219
|
}
|
|
@@ -998,36 +1233,36 @@ class Ze {
|
|
|
998
1233
|
* Get or create a refresh lock for a schema
|
|
999
1234
|
* Prevents concurrent fetches for the same schema
|
|
1000
1235
|
*/
|
|
1001
|
-
async withRefreshLock(e,
|
|
1002
|
-
return this.memoryCache.withRefreshLock(e,
|
|
1236
|
+
async withRefreshLock(e, n) {
|
|
1237
|
+
return this.memoryCache.withRefreshLock(e, n);
|
|
1003
1238
|
}
|
|
1004
1239
|
/**
|
|
1005
1240
|
* Merge new items with cached items
|
|
1006
1241
|
* Deduplicates by item ID and sorts by timeCreated (descending)
|
|
1007
1242
|
*/
|
|
1008
|
-
mergeItems(e,
|
|
1009
|
-
const
|
|
1010
|
-
for (const
|
|
1011
|
-
const
|
|
1012
|
-
|
|
1243
|
+
mergeItems(e, n) {
|
|
1244
|
+
const s = /* @__PURE__ */ new Map();
|
|
1245
|
+
for (const a of e) {
|
|
1246
|
+
const o = a.id || a.seedUid || a.SeedUid || "";
|
|
1247
|
+
o && s.set(o, a);
|
|
1013
1248
|
}
|
|
1014
|
-
for (const
|
|
1015
|
-
const
|
|
1016
|
-
|
|
1249
|
+
for (const a of n) {
|
|
1250
|
+
const o = a.id || a.seedUid || a.SeedUid || "";
|
|
1251
|
+
o ? s.set(o, a) : s.set(`temp-${Date.now()}-${Math.random()}`, a);
|
|
1017
1252
|
}
|
|
1018
|
-
const
|
|
1019
|
-
return
|
|
1020
|
-
const i =
|
|
1021
|
-
return (
|
|
1022
|
-
}),
|
|
1253
|
+
const r = Array.from(s.values());
|
|
1254
|
+
return r.sort((a, o) => {
|
|
1255
|
+
const i = a.timeCreated || 0;
|
|
1256
|
+
return (o.timeCreated || 0) - i;
|
|
1257
|
+
}), r;
|
|
1023
1258
|
}
|
|
1024
1259
|
/**
|
|
1025
1260
|
* Filter items to only include those newer than the given timestamp
|
|
1026
1261
|
*/
|
|
1027
|
-
filterNewItems(e,
|
|
1028
|
-
return e.filter((
|
|
1029
|
-
const
|
|
1030
|
-
return
|
|
1262
|
+
filterNewItems(e, n) {
|
|
1263
|
+
return e.filter((s) => {
|
|
1264
|
+
const r = s.timeCreated;
|
|
1265
|
+
return r && r > n;
|
|
1031
1266
|
});
|
|
1032
1267
|
}
|
|
1033
1268
|
/**
|
|
@@ -1053,22 +1288,22 @@ class Ze {
|
|
|
1053
1288
|
if (!this.config.enabled || !this.config.imageMetadata?.enabled)
|
|
1054
1289
|
return null;
|
|
1055
1290
|
try {
|
|
1056
|
-
let
|
|
1057
|
-
return
|
|
1058
|
-
} catch (
|
|
1059
|
-
return console.error(`Error getting image metadata cache for ${e}:`,
|
|
1291
|
+
let n = this.memoryCache.getImageMetadata(e);
|
|
1292
|
+
return n ? (this.stats.hits++, n) : (n = await this.fileCache.getImageMetadata(e), n ? (this.memoryCache.setImageMetadata(e, n), this.stats.hits++, n) : (this.stats.misses++, null));
|
|
1293
|
+
} catch (n) {
|
|
1294
|
+
return console.error(`Error getting image metadata cache for ${e}:`, n), this.stats.errors++, null;
|
|
1060
1295
|
}
|
|
1061
1296
|
}
|
|
1062
1297
|
/**
|
|
1063
1298
|
* Set cached image metadata for a transaction ID
|
|
1064
1299
|
* Updates both memory and file cache
|
|
1065
1300
|
*/
|
|
1066
|
-
async setImageMetadata(e,
|
|
1301
|
+
async setImageMetadata(e, n) {
|
|
1067
1302
|
if (!(!this.config.enabled || !this.config.imageMetadata?.enabled))
|
|
1068
1303
|
try {
|
|
1069
|
-
this.memoryCache.setImageMetadata(e,
|
|
1070
|
-
} catch (
|
|
1071
|
-
console.error(`Error setting image metadata cache for ${e}:`,
|
|
1304
|
+
this.memoryCache.setImageMetadata(e, n), await this.fileCache.setImageMetadata(e, n);
|
|
1305
|
+
} catch (s) {
|
|
1306
|
+
console.error(`Error setting image metadata cache for ${e}:`, s), this.stats.errors++;
|
|
1072
1307
|
}
|
|
1073
1308
|
}
|
|
1074
1309
|
/**
|
|
@@ -1083,33 +1318,33 @@ class Ze {
|
|
|
1083
1318
|
};
|
|
1084
1319
|
}
|
|
1085
1320
|
}
|
|
1086
|
-
function
|
|
1087
|
-
const
|
|
1088
|
-
let
|
|
1089
|
-
|
|
1090
|
-
const
|
|
1321
|
+
function ce() {
|
|
1322
|
+
const t = parseInt(process.env.CACHE_TTL || "3600", 10), e = process.env.CACHE_DIR || "./cache", n = process.env.CACHE_ENABLED === "false" || process.env.CACHE_ENABLED === "0" || process.env.CACHE_ENABLED === "no" || process.env.CACHE_ENABLED === "off", s = process.env.CACHE_ENABLED === "true" || process.env.CACHE_ENABLED === "1" || process.env.CACHE_ENABLED === "yes", r = process.env.NODE_ENV === "development";
|
|
1323
|
+
let a;
|
|
1324
|
+
n ? a = !1 : s ? a = !0 : r ? a = !1 : a = !0;
|
|
1325
|
+
const o = process.env.CACHE_BACKGROUND_REFRESH === "true", i = parseInt(
|
|
1091
1326
|
process.env.CACHE_REFRESH_INTERVAL || "300",
|
|
1092
1327
|
10
|
|
1093
1328
|
);
|
|
1094
|
-
|
|
1095
|
-
const
|
|
1096
|
-
enabled:
|
|
1329
|
+
a || console.log(`⚠️ Cache is DISABLED (${n ? "CACHE_ENABLED=false" : r ? "NODE_ENV=development" : "CACHE_ENABLED=false"})`);
|
|
1330
|
+
const c = process.env.IMAGE_METADATA_ENABLED !== "false", d = parseInt(process.env.IMAGE_METADATA_TTL || "604800", 10), f = process.env.IMAGE_METADATA_GATEWAYS ? process.env.IMAGE_METADATA_GATEWAYS.split(",").map((m) => m.trim()) : [...Ee], p = parseInt(process.env.IMAGE_METADATA_TIMEOUT || "5000", 10), w = {
|
|
1331
|
+
enabled: c,
|
|
1097
1332
|
ttl: d,
|
|
1098
1333
|
gateways: f,
|
|
1099
1334
|
timeout: p
|
|
1100
|
-
},
|
|
1335
|
+
}, h = parseInt(process.env.CACHE_PAGE_TTL || "300", 10), C = parseInt(process.env.CACHE_ARCHIVE_TTL || "86400", 10);
|
|
1101
1336
|
return {
|
|
1102
|
-
ttl:
|
|
1337
|
+
ttl: t,
|
|
1103
1338
|
cacheDir: e,
|
|
1104
|
-
enabled:
|
|
1105
|
-
backgroundRefresh:
|
|
1339
|
+
enabled: a,
|
|
1340
|
+
backgroundRefresh: o,
|
|
1106
1341
|
refreshInterval: i,
|
|
1107
|
-
imageMetadata:
|
|
1108
|
-
pageTtl:
|
|
1109
|
-
archiveTtl:
|
|
1342
|
+
imageMetadata: w,
|
|
1343
|
+
pageTtl: h,
|
|
1344
|
+
archiveTtl: C
|
|
1110
1345
|
};
|
|
1111
1346
|
}
|
|
1112
|
-
class
|
|
1347
|
+
class ye {
|
|
1113
1348
|
config;
|
|
1114
1349
|
constructor(e) {
|
|
1115
1350
|
this.config = e;
|
|
@@ -1118,19 +1353,19 @@ class oe {
|
|
|
1118
1353
|
* Detect if an Arweave transaction ID links to an image and extract metadata
|
|
1119
1354
|
*/
|
|
1120
1355
|
async detectImage(e) {
|
|
1121
|
-
const
|
|
1122
|
-
for (const
|
|
1356
|
+
const n = this.config.gateways || [...Ee];
|
|
1357
|
+
for (const s of n)
|
|
1123
1358
|
try {
|
|
1124
|
-
const
|
|
1125
|
-
if (
|
|
1126
|
-
return
|
|
1127
|
-
} catch (
|
|
1128
|
-
console.warn(`Failed to fetch from gateway ${
|
|
1359
|
+
const r = `https://${s}/${e}`, a = await this.getImageMetadata(r);
|
|
1360
|
+
if (a.isImage)
|
|
1361
|
+
return a;
|
|
1362
|
+
} catch (r) {
|
|
1363
|
+
console.warn(`Failed to fetch from gateway ${s} for transaction ${e}:`, r);
|
|
1129
1364
|
continue;
|
|
1130
1365
|
}
|
|
1131
1366
|
return {
|
|
1132
1367
|
isImage: !1,
|
|
1133
|
-
url: `https://${
|
|
1368
|
+
url: `https://${n[0]}/${e}`
|
|
1134
1369
|
};
|
|
1135
1370
|
}
|
|
1136
1371
|
/**
|
|
@@ -1138,59 +1373,59 @@ class oe {
|
|
|
1138
1373
|
*/
|
|
1139
1374
|
async getImageMetadata(e) {
|
|
1140
1375
|
try {
|
|
1141
|
-
const
|
|
1142
|
-
if (!
|
|
1376
|
+
const n = await this.fetchWithTimeout(e, { method: "HEAD" });
|
|
1377
|
+
if (!n.ok)
|
|
1143
1378
|
return { isImage: !1, url: e };
|
|
1144
|
-
const
|
|
1145
|
-
if (!this.isImageContentType(
|
|
1379
|
+
const s = n.headers.get("content-type") || "", r = n.headers.get("content-length");
|
|
1380
|
+
if (!this.isImageContentType(s))
|
|
1146
1381
|
return {
|
|
1147
1382
|
isImage: !1,
|
|
1148
1383
|
url: e,
|
|
1149
|
-
mimeType:
|
|
1150
|
-
size:
|
|
1384
|
+
mimeType: s || void 0,
|
|
1385
|
+
size: r ? parseInt(r, 10) : void 0
|
|
1151
1386
|
};
|
|
1152
|
-
const
|
|
1387
|
+
const a = await this.fetchWithTimeout(e, {
|
|
1153
1388
|
headers: {
|
|
1154
1389
|
Range: "bytes=0-8192"
|
|
1155
1390
|
// First 8KB should be enough for most image headers
|
|
1156
1391
|
}
|
|
1157
1392
|
});
|
|
1158
|
-
if (!
|
|
1159
|
-
return await this.getImageMetadataFromFullRequest(e,
|
|
1160
|
-
const
|
|
1393
|
+
if (!a.ok)
|
|
1394
|
+
return await this.getImageMetadataFromFullRequest(e, s, r);
|
|
1395
|
+
const o = Buffer.from(await a.arrayBuffer()), i = this.extractImageDimensions(o, s), c = this.getImageFormat(s, o);
|
|
1161
1396
|
return {
|
|
1162
1397
|
isImage: !0,
|
|
1163
1398
|
url: e,
|
|
1164
|
-
mimeType:
|
|
1399
|
+
mimeType: s,
|
|
1165
1400
|
width: i.width,
|
|
1166
1401
|
height: i.height,
|
|
1167
|
-
size:
|
|
1168
|
-
format:
|
|
1402
|
+
size: r ? parseInt(r, 10) : void 0,
|
|
1403
|
+
format: c
|
|
1169
1404
|
};
|
|
1170
|
-
} catch (
|
|
1171
|
-
return console.warn(`Error fetching image metadata from ${e}:`,
|
|
1405
|
+
} catch (n) {
|
|
1406
|
+
return console.warn(`Error fetching image metadata from ${e}:`, n), { isImage: !1, url: e };
|
|
1172
1407
|
}
|
|
1173
1408
|
}
|
|
1174
1409
|
/**
|
|
1175
1410
|
* Fetch image metadata from full request (fallback when range requests fail)
|
|
1176
1411
|
*/
|
|
1177
|
-
async getImageMetadataFromFullRequest(e,
|
|
1412
|
+
async getImageMetadataFromFullRequest(e, n, s) {
|
|
1178
1413
|
try {
|
|
1179
|
-
const
|
|
1180
|
-
if (!
|
|
1414
|
+
const r = await this.fetchWithTimeout(e);
|
|
1415
|
+
if (!r.ok)
|
|
1181
1416
|
return { isImage: !1, url: e };
|
|
1182
|
-
const
|
|
1417
|
+
const a = Buffer.from(await r.arrayBuffer()), o = this.extractImageDimensions(a, n), i = this.getImageFormat(n, a);
|
|
1183
1418
|
return {
|
|
1184
1419
|
isImage: !0,
|
|
1185
1420
|
url: e,
|
|
1186
|
-
mimeType:
|
|
1187
|
-
width:
|
|
1188
|
-
height:
|
|
1189
|
-
size:
|
|
1421
|
+
mimeType: n,
|
|
1422
|
+
width: o.width,
|
|
1423
|
+
height: o.height,
|
|
1424
|
+
size: a.length,
|
|
1190
1425
|
format: i
|
|
1191
1426
|
};
|
|
1192
|
-
} catch (
|
|
1193
|
-
return console.warn(`Error in full request for ${e}:`,
|
|
1427
|
+
} catch (r) {
|
|
1428
|
+
return console.warn(`Error in full request for ${e}:`, r), { isImage: !1, url: e };
|
|
1194
1429
|
}
|
|
1195
1430
|
}
|
|
1196
1431
|
/**
|
|
@@ -1202,88 +1437,195 @@ class oe {
|
|
|
1202
1437
|
/**
|
|
1203
1438
|
* Extract image dimensions from buffer
|
|
1204
1439
|
*/
|
|
1205
|
-
extractImageDimensions(e,
|
|
1440
|
+
extractImageDimensions(e, n) {
|
|
1206
1441
|
try {
|
|
1207
|
-
const
|
|
1208
|
-
if (
|
|
1442
|
+
const s = le(e);
|
|
1443
|
+
if (s.width && s.height)
|
|
1209
1444
|
return {
|
|
1210
|
-
width:
|
|
1211
|
-
height:
|
|
1445
|
+
width: s.width,
|
|
1446
|
+
height: s.height
|
|
1212
1447
|
};
|
|
1213
|
-
} catch (
|
|
1214
|
-
console.warn("Failed to extract dimensions:",
|
|
1448
|
+
} catch (s) {
|
|
1449
|
+
console.warn("Failed to extract dimensions:", s);
|
|
1215
1450
|
}
|
|
1216
1451
|
return { width: 0, height: 0 };
|
|
1217
1452
|
}
|
|
1218
1453
|
/**
|
|
1219
1454
|
* Get image format from Content-Type or buffer analysis
|
|
1220
1455
|
*/
|
|
1221
|
-
getImageFormat(e,
|
|
1456
|
+
getImageFormat(e, n) {
|
|
1222
1457
|
if (e) {
|
|
1223
|
-
const
|
|
1224
|
-
if (
|
|
1225
|
-
const
|
|
1226
|
-
return
|
|
1458
|
+
const s = e.toLowerCase().match(/image\/([^;]+)/);
|
|
1459
|
+
if (s && s[1]) {
|
|
1460
|
+
const r = s[1].toLowerCase();
|
|
1461
|
+
return r === "jpeg" ? "jpeg" : r === "png" ? "png" : r === "gif" ? "gif" : r === "webp" ? "webp" : r === "svg+xml" ? "svg" : r;
|
|
1227
1462
|
}
|
|
1228
1463
|
}
|
|
1229
1464
|
try {
|
|
1230
|
-
const
|
|
1231
|
-
if (
|
|
1232
|
-
return
|
|
1465
|
+
const s = le(n);
|
|
1466
|
+
if (s.type)
|
|
1467
|
+
return s.type.toLowerCase();
|
|
1233
1468
|
} catch {
|
|
1234
1469
|
}
|
|
1235
1470
|
}
|
|
1236
1471
|
/**
|
|
1237
1472
|
* Fetch with timeout
|
|
1238
1473
|
*/
|
|
1239
|
-
async fetchWithTimeout(e,
|
|
1240
|
-
const
|
|
1474
|
+
async fetchWithTimeout(e, n = {}) {
|
|
1475
|
+
const s = new AbortController(), r = setTimeout(() => s.abort(), this.config.timeout);
|
|
1241
1476
|
try {
|
|
1242
|
-
const
|
|
1243
|
-
...
|
|
1244
|
-
signal:
|
|
1477
|
+
const a = await fetch(e, {
|
|
1478
|
+
...n,
|
|
1479
|
+
signal: s.signal
|
|
1245
1480
|
});
|
|
1246
|
-
return clearTimeout(
|
|
1247
|
-
} catch (
|
|
1248
|
-
throw clearTimeout(
|
|
1481
|
+
return clearTimeout(r), a;
|
|
1482
|
+
} catch (a) {
|
|
1483
|
+
throw clearTimeout(r), a instanceof Error && a.name === "AbortError" ? new Error(`Request timeout after ${this.config.timeout}ms`) : a;
|
|
1249
1484
|
}
|
|
1250
1485
|
}
|
|
1251
1486
|
}
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1487
|
+
function se(t, e) {
|
|
1488
|
+
for (const n of e) {
|
|
1489
|
+
const s = t[n];
|
|
1490
|
+
if (typeof s == "string" && s.trim() !== "")
|
|
1491
|
+
return s;
|
|
1257
1492
|
}
|
|
1258
|
-
return
|
|
1493
|
+
return "";
|
|
1259
1494
|
}
|
|
1260
|
-
|
|
1261
|
-
|
|
1495
|
+
const Pe = ["summary", "Summary", "description", "Description", "text", "Text"], Re = ["html", "Html", "body", "Body", "content", "Content"], bt = ["summary", "Summary", "description", "Description", "text", "Text"];
|
|
1496
|
+
function we(t, e) {
|
|
1497
|
+
const n = de(t.model) - de(e.model);
|
|
1498
|
+
if (n !== 0) return n;
|
|
1499
|
+
const s = t.key.localeCompare(e.key);
|
|
1500
|
+
return s !== 0 ? s : t.index - e.index;
|
|
1501
|
+
}
|
|
1502
|
+
function vt(t) {
|
|
1503
|
+
const e = Q(t), n = ee(t);
|
|
1504
|
+
let s = null;
|
|
1505
|
+
if (e)
|
|
1506
|
+
for (const [r, a] of Object.entries(e)) {
|
|
1507
|
+
if (!B(a)) continue;
|
|
1508
|
+
const o = t[r];
|
|
1509
|
+
if (typeof o != "string" || o.trim() === "") continue;
|
|
1510
|
+
const i = { model: a, key: r, index: 0, value: o };
|
|
1511
|
+
(!s || we(i, s) < 0) && (s = i);
|
|
1512
|
+
}
|
|
1513
|
+
if (n)
|
|
1514
|
+
for (const [r, a] of Object.entries(n)) {
|
|
1515
|
+
const o = t[r];
|
|
1516
|
+
if (!Array.isArray(o)) continue;
|
|
1517
|
+
const i = Math.min(a.length, o.length);
|
|
1518
|
+
for (let c = 0; c < i; c++) {
|
|
1519
|
+
const d = a[c];
|
|
1520
|
+
if (!B(d)) continue;
|
|
1521
|
+
const f = o[c];
|
|
1522
|
+
if (typeof f != "string" || f.trim() === "") continue;
|
|
1523
|
+
const p = { model: d, key: r, index: c, value: f };
|
|
1524
|
+
(!s || we(p, s) < 0) && (s = p);
|
|
1525
|
+
}
|
|
1526
|
+
}
|
|
1527
|
+
return s?.value ?? "";
|
|
1528
|
+
}
|
|
1529
|
+
function kt(t) {
|
|
1530
|
+
return se(t, Pe);
|
|
1531
|
+
}
|
|
1532
|
+
function xt(t) {
|
|
1533
|
+
const e = vt(t);
|
|
1534
|
+
if (e !== "") return e;
|
|
1535
|
+
const n = se(t, Re);
|
|
1536
|
+
return n !== "" ? n : se(t, bt);
|
|
1537
|
+
}
|
|
1538
|
+
function q(t) {
|
|
1539
|
+
return typeof t != "string" ? !1 : t.includes("data:image/") && t.includes(";base64,");
|
|
1540
|
+
}
|
|
1541
|
+
function Lt(t) {
|
|
1542
|
+
const e = Q(t);
|
|
1543
|
+
if (e) {
|
|
1544
|
+
for (const [s, r] of Object.entries(e))
|
|
1545
|
+
if (B(r) && q(t[s]))
|
|
1546
|
+
return !0;
|
|
1547
|
+
}
|
|
1548
|
+
const n = ee(t);
|
|
1549
|
+
if (n)
|
|
1550
|
+
for (const [s, r] of Object.entries(n)) {
|
|
1551
|
+
const a = t[s];
|
|
1552
|
+
if (!Array.isArray(a)) continue;
|
|
1553
|
+
const o = Math.min(r.length, a.length);
|
|
1554
|
+
for (let i = 0; i < o; i++)
|
|
1555
|
+
if (B(r[i]) && q(a[i]))
|
|
1556
|
+
return !0;
|
|
1557
|
+
}
|
|
1558
|
+
return !1;
|
|
1559
|
+
}
|
|
1560
|
+
function Pt(t) {
|
|
1561
|
+
if (Lt(t)) return !0;
|
|
1562
|
+
for (const e of Re)
|
|
1563
|
+
if (q(t[e])) return !0;
|
|
1564
|
+
for (const e of Pe)
|
|
1565
|
+
if (q(t[e])) return !0;
|
|
1566
|
+
return !1;
|
|
1567
|
+
}
|
|
1568
|
+
function Rt(t, e = "omit_items") {
|
|
1569
|
+
return e === "include_items" ? [...t] : t.filter((n) => !Pt(n));
|
|
1570
|
+
}
|
|
1571
|
+
function Ot(t) {
|
|
1572
|
+
if (t != null) {
|
|
1573
|
+
if (typeof t == "string") {
|
|
1574
|
+
if (t.startsWith("http://") || t.startsWith("https://")) return t;
|
|
1575
|
+
try {
|
|
1576
|
+
return j(t);
|
|
1577
|
+
} catch {
|
|
1578
|
+
return;
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1581
|
+
if (typeof t == "object" && !Array.isArray(t)) {
|
|
1582
|
+
const e = t, n = e.arweaveUrl;
|
|
1583
|
+
if (typeof n == "string" && n.trim()) return n.trim();
|
|
1584
|
+
const s = e.storageTransactionId ?? e.storage_transaction_id;
|
|
1585
|
+
if (s && typeof s == "string" && s.trim())
|
|
1586
|
+
try {
|
|
1587
|
+
return j(s.trim());
|
|
1588
|
+
} catch {
|
|
1589
|
+
return;
|
|
1590
|
+
}
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1593
|
+
}
|
|
1594
|
+
let O, k = null, V = null;
|
|
1595
|
+
function Oe() {
|
|
1596
|
+
if (!V) {
|
|
1597
|
+
const t = ce();
|
|
1598
|
+
V = new Ut(t);
|
|
1599
|
+
}
|
|
1600
|
+
return V;
|
|
1262
1601
|
}
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1602
|
+
function en() {
|
|
1603
|
+
V = null;
|
|
1604
|
+
}
|
|
1605
|
+
const Nt = async () => {
|
|
1606
|
+
if (k)
|
|
1607
|
+
return k;
|
|
1608
|
+
if (!O)
|
|
1609
|
+
return k = (async () => {
|
|
1268
1610
|
try {
|
|
1269
|
-
console.log("Initializing Seed Protocol client..."), await
|
|
1611
|
+
console.log("Initializing Seed Protocol client..."), await L.init({ config: {
|
|
1270
1612
|
endpoints: {
|
|
1271
1613
|
filePaths: "app-files",
|
|
1272
1614
|
files: "/app-files"
|
|
1273
1615
|
},
|
|
1274
|
-
arweaveDomain:
|
|
1275
|
-
}, addresses: [] }), console.log("✅ Seed Protocol client initialized successfully"),
|
|
1276
|
-
} catch (
|
|
1277
|
-
throw console.error("❌ Failed to initialize Seed Protocol client:",
|
|
1616
|
+
arweaveDomain: Xe
|
|
1617
|
+
}, addresses: [] }), console.log("✅ Seed Protocol client initialized successfully"), O = L, k = null;
|
|
1618
|
+
} catch (t) {
|
|
1619
|
+
throw console.error("❌ Failed to initialize Seed Protocol client:", t), k = null, t;
|
|
1278
1620
|
}
|
|
1279
|
-
})(),
|
|
1280
|
-
},
|
|
1621
|
+
})(), k;
|
|
1622
|
+
}, jt = async () => O || (k ? (await k, O) : (await Nt(), O)), tn = async () => {
|
|
1281
1623
|
try {
|
|
1282
|
-
console.log("Tearing down Seed Protocol client..."), typeof
|
|
1283
|
-
} catch (
|
|
1284
|
-
console.error("❌ Failed to teardown Seed Protocol client:",
|
|
1624
|
+
console.log("Tearing down Seed Protocol client..."), typeof L.stop == "function" && (await L.stop(), console.log("✅ Seed Protocol client stopped")), typeof L.unload == "function" && (await L.unload(), console.log("✅ Seed Protocol client unloaded")), console.log("✅ Seed Protocol client teardown complete");
|
|
1625
|
+
} catch (t) {
|
|
1626
|
+
console.error("❌ Failed to teardown Seed Protocol client:", t);
|
|
1285
1627
|
}
|
|
1286
|
-
},
|
|
1628
|
+
}, E = {
|
|
1287
1629
|
title: "Seed Protocol",
|
|
1288
1630
|
description: "Content published via Seed Protocol",
|
|
1289
1631
|
siteUrl: "https://seedprotocol.io",
|
|
@@ -1296,263 +1638,266 @@ const Qe = async () => {
|
|
|
1296
1638
|
link: "https://seedprotocol.io"
|
|
1297
1639
|
}
|
|
1298
1640
|
};
|
|
1299
|
-
async function
|
|
1300
|
-
const
|
|
1641
|
+
async function Ce(t, e, n) {
|
|
1642
|
+
const s = t.filter(
|
|
1301
1643
|
(i) => i.storageTransactionId || i.storage_transaction_id
|
|
1302
1644
|
);
|
|
1303
|
-
if (
|
|
1304
|
-
return
|
|
1305
|
-
console.log(`Enriching ${
|
|
1306
|
-
const
|
|
1307
|
-
const
|
|
1308
|
-
if (!
|
|
1645
|
+
if (s.length === 0)
|
|
1646
|
+
return t;
|
|
1647
|
+
console.log(`Enriching ${s.length} items with image metadata`);
|
|
1648
|
+
const r = s.map(async (i) => {
|
|
1649
|
+
const c = i.storageTransactionId || i.storage_transaction_id;
|
|
1650
|
+
if (!c) return i;
|
|
1309
1651
|
try {
|
|
1310
|
-
let d = await
|
|
1311
|
-
return d || (console.log(`Detecting image for transaction ${
|
|
1652
|
+
let d = await n.getImageMetadata(c);
|
|
1653
|
+
return d || (console.log(`Detecting image for transaction ${c}`), d = await e.detectImage(c), await n.setImageMetadata(c, d)), d.isImage && (i._imageMetadata = d, i._hasImage = !0), i;
|
|
1312
1654
|
} catch (d) {
|
|
1313
|
-
return console.warn(`Error enriching item with transaction ${
|
|
1655
|
+
return console.warn(`Error enriching item with transaction ${c}:`, d), i;
|
|
1314
1656
|
}
|
|
1315
|
-
}),
|
|
1316
|
-
return
|
|
1317
|
-
const
|
|
1318
|
-
|
|
1319
|
-
}),
|
|
1320
|
-
const
|
|
1321
|
-
return
|
|
1657
|
+
}), a = await Promise.all(r), o = /* @__PURE__ */ new Map();
|
|
1658
|
+
return a.forEach((i) => {
|
|
1659
|
+
const c = i.id || i.seedUid || i.SeedUid || "";
|
|
1660
|
+
c && o.set(c, i);
|
|
1661
|
+
}), t.map((i) => {
|
|
1662
|
+
const c = i.id || i.seedUid || i.SeedUid || "";
|
|
1663
|
+
return o.get(c) || i;
|
|
1322
1664
|
});
|
|
1323
1665
|
}
|
|
1324
|
-
function
|
|
1325
|
-
const { schemaName:
|
|
1326
|
-
return
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1666
|
+
function Bt(t, e) {
|
|
1667
|
+
const { schemaName: n, siteUrl: s, itemUrlBase: r, itemUrlPath: a, richTextDataUriImages: o = "omit_items" } = e;
|
|
1668
|
+
return Rt(
|
|
1669
|
+
t,
|
|
1670
|
+
o
|
|
1671
|
+
).map((c) => {
|
|
1672
|
+
const d = c.id || c.seedUid || c.SeedUid || c.storageTransactionId || c.storage_transaction_id, f = r != null ? `${r.replace(/\/$/, "")}/${(a ?? "attestation/view").replace(/^\//, "")}/${d}` : `${s}/${b(n)}/${d}`, p = c.link || c.Link || c.import_url || c.importUrl || f;
|
|
1673
|
+
let w;
|
|
1674
|
+
if (c.pubDate || c.PubDate) {
|
|
1675
|
+
const y = c.pubDate || c.PubDate;
|
|
1676
|
+
w = new Date(y);
|
|
1677
|
+
} else if (c.timeCreated)
|
|
1678
|
+
w = new Date(c.timeCreated * 1e3);
|
|
1679
|
+
else if (c.publishedAt || c.createdAt || c.updatedAt) {
|
|
1680
|
+
const y = c.publishedAt || c.createdAt || c.updatedAt;
|
|
1681
|
+
w = y && typeof y == "object" && y.constructor === Date ? y : new Date(y);
|
|
1337
1682
|
} else
|
|
1338
|
-
|
|
1339
|
-
const
|
|
1340
|
-
...
|
|
1683
|
+
w = /* @__PURE__ */ new Date();
|
|
1684
|
+
const h = kt(c), C = xt(c), m = {
|
|
1685
|
+
...c,
|
|
1341
1686
|
// Preserve all dynamic properties first
|
|
1342
1687
|
// Map to standard feed fields
|
|
1343
|
-
id:
|
|
1344
|
-
title:
|
|
1345
|
-
link:
|
|
1346
|
-
description:
|
|
1347
|
-
content:
|
|
1348
|
-
pubDate:
|
|
1349
|
-
date:
|
|
1688
|
+
id: d,
|
|
1689
|
+
title: c.title || c.Title || "Untitled",
|
|
1690
|
+
link: p,
|
|
1691
|
+
description: h,
|
|
1692
|
+
content: C,
|
|
1693
|
+
pubDate: w,
|
|
1694
|
+
date: w,
|
|
1350
1695
|
// Map guid - use full URL when available for proper permalink
|
|
1351
|
-
guid:
|
|
1696
|
+
guid: c.guid || c.Guid || c.link || c.Link || p
|
|
1352
1697
|
};
|
|
1353
|
-
if (
|
|
1354
|
-
const
|
|
1355
|
-
|
|
1698
|
+
if (typeof m.html == "string" && m.Html === void 0 && (m.Html = m.html), typeof m.Html == "string" && m.html === void 0 && (m.html = m.Html), typeof m.body == "string" && m.Body === void 0 && (m.Body = m.body), typeof m.Body == "string" && m.body === void 0 && (m.body = m.Body), c._imageMetadata && c._hasImage) {
|
|
1699
|
+
const y = c._imageMetadata;
|
|
1700
|
+
m._imageMetadata = y, m._hasImage = !0;
|
|
1356
1701
|
}
|
|
1357
|
-
return Object.keys(
|
|
1358
|
-
const
|
|
1359
|
-
if (typeof
|
|
1360
|
-
const
|
|
1361
|
-
isNaN(
|
|
1702
|
+
return Object.keys(m).forEach((y) => {
|
|
1703
|
+
const l = m[y];
|
|
1704
|
+
if (typeof l == "string" && /date|time|published|created|updated/i.test(y) && y !== "pubDate" && y !== "date") {
|
|
1705
|
+
const u = new Date(l);
|
|
1706
|
+
isNaN(u.getTime()) || (m[y] = u);
|
|
1362
1707
|
}
|
|
1363
|
-
}),
|
|
1708
|
+
}), m;
|
|
1364
1709
|
});
|
|
1365
1710
|
}
|
|
1366
|
-
const
|
|
1367
|
-
const
|
|
1368
|
-
if (
|
|
1369
|
-
const
|
|
1370
|
-
|
|
1371
|
-
}
|
|
1372
|
-
if (
|
|
1373
|
-
for (const
|
|
1374
|
-
|
|
1375
|
-
const
|
|
1711
|
+
const Ne = (t, e, n, s, r, a, o, i) => {
|
|
1712
|
+
const c = b(e), d = `${E.siteUrl}/${c}/${n}`, f = s ? `${d}?v=${s}` : d, p = `${E.title} - ${Wt(c)}`, w = /* @__PURE__ */ new Date(), h = G(), C = [];
|
|
1713
|
+
if (r) {
|
|
1714
|
+
const y = r.baseUrl.replace(/\?.*$/, ""), l = y.includes("?") ? "&" : "?";
|
|
1715
|
+
r.hasNext && C.push({ rel: "next", href: `${y}${l}page=${r.page + 1}` }), r.page > 1 && (C.push({ rel: "previous", href: `${y}${l}page=${r.page - 1}` }), C.push({ rel: "first", href: `${y}${l}page=1` }));
|
|
1716
|
+
}
|
|
1717
|
+
if (a?.length)
|
|
1718
|
+
for (const y of a)
|
|
1719
|
+
C.push({ rel: y.rel, href: y.href });
|
|
1720
|
+
const m = Bt(t, {
|
|
1376
1721
|
schemaName: e,
|
|
1377
|
-
siteUrl:
|
|
1378
|
-
itemUrlBase:
|
|
1379
|
-
itemUrlPath:
|
|
1722
|
+
siteUrl: E.siteUrl,
|
|
1723
|
+
itemUrlBase: h.itemUrlBase,
|
|
1724
|
+
itemUrlPath: h.itemUrlPath,
|
|
1725
|
+
richTextDataUriImages: i?.richTextDataUriImages ?? h.richTextDataUriImages
|
|
1380
1726
|
});
|
|
1381
|
-
switch (
|
|
1727
|
+
switch (n) {
|
|
1382
1728
|
case "atom": {
|
|
1383
|
-
const
|
|
1384
|
-
{ href:
|
|
1385
|
-
{ href:
|
|
1729
|
+
const y = [
|
|
1730
|
+
{ href: f, rel: "self" },
|
|
1731
|
+
{ href: E.siteUrl }
|
|
1386
1732
|
];
|
|
1387
|
-
for (const u of
|
|
1388
|
-
|
|
1733
|
+
for (const u of C)
|
|
1734
|
+
y.push({
|
|
1389
1735
|
href: u.href,
|
|
1390
1736
|
rel: u.rel,
|
|
1391
1737
|
type: u.type
|
|
1392
1738
|
});
|
|
1393
|
-
const
|
|
1394
|
-
id:
|
|
1395
|
-
title:
|
|
1396
|
-
updated:
|
|
1397
|
-
links:
|
|
1398
|
-
subtitle:
|
|
1399
|
-
rights:
|
|
1400
|
-
author:
|
|
1401
|
-
name:
|
|
1402
|
-
email:
|
|
1403
|
-
uri:
|
|
1739
|
+
const l = {
|
|
1740
|
+
id: f,
|
|
1741
|
+
title: p,
|
|
1742
|
+
updated: w,
|
|
1743
|
+
links: y,
|
|
1744
|
+
subtitle: E.description,
|
|
1745
|
+
rights: E.copyright,
|
|
1746
|
+
author: E.author ? {
|
|
1747
|
+
name: E.author.name,
|
|
1748
|
+
email: E.author.email,
|
|
1749
|
+
uri: E.author.link
|
|
1404
1750
|
} : void 0,
|
|
1405
|
-
entries:
|
|
1406
|
-
const
|
|
1751
|
+
entries: m.map((u) => {
|
|
1752
|
+
const g = {
|
|
1407
1753
|
id: u.id || u.link,
|
|
1408
1754
|
title: u.title || "Untitled",
|
|
1409
|
-
updated: u.date || u.pubDate ||
|
|
1755
|
+
updated: u.date || u.pubDate || w,
|
|
1410
1756
|
links: u.link ? [{ href: u.link }] : [],
|
|
1411
1757
|
...u
|
|
1412
1758
|
// Preserve all dynamic properties
|
|
1413
1759
|
};
|
|
1414
|
-
if (u.content && (
|
|
1415
|
-
const
|
|
1416
|
-
if (
|
|
1417
|
-
href:
|
|
1760
|
+
if (u.content && (g.content = u.content), u.description && (g.summary = u.description), u._imageMetadata && u._hasImage) {
|
|
1761
|
+
const D = u._imageMetadata;
|
|
1762
|
+
if (g.links || (g.links = []), g.links.push({
|
|
1763
|
+
href: D.url,
|
|
1418
1764
|
rel: "enclosure",
|
|
1419
|
-
type:
|
|
1420
|
-
length:
|
|
1421
|
-
}),
|
|
1422
|
-
const T = `<img src="${
|
|
1423
|
-
|
|
1424
|
-
${
|
|
1425
|
-
${
|
|
1765
|
+
type: D.mimeType || "image/jpeg",
|
|
1766
|
+
length: D.size
|
|
1767
|
+
}), D.url && g.content && !g.content.includes(D.url)) {
|
|
1768
|
+
const T = `<img src="${D.url}" alt="${u.title || ""}"${D.width ? ` width="${D.width}"` : ""}${D.height ? ` height="${D.height}"` : ""} />`;
|
|
1769
|
+
g.content = typeof g.content == "string" ? `${T}
|
|
1770
|
+
${g.content}` : { type: "html", value: `${T}
|
|
1771
|
+
${g.content.value || g.content}` };
|
|
1426
1772
|
}
|
|
1427
1773
|
}
|
|
1428
|
-
return
|
|
1774
|
+
return g;
|
|
1429
1775
|
})
|
|
1430
1776
|
};
|
|
1431
|
-
return Promise.resolve(
|
|
1777
|
+
return Promise.resolve(qe(l));
|
|
1432
1778
|
}
|
|
1433
1779
|
case "json": {
|
|
1434
|
-
const
|
|
1435
|
-
title:
|
|
1436
|
-
home_page_url:
|
|
1437
|
-
feed_url:
|
|
1438
|
-
...
|
|
1439
|
-
description:
|
|
1440
|
-
author:
|
|
1441
|
-
name:
|
|
1442
|
-
url:
|
|
1780
|
+
const y = r?.hasNext ? `${r.baseUrl.replace(/\?.*$/, "")}?page=${r.page + 1}` : void 0, l = {
|
|
1781
|
+
title: p,
|
|
1782
|
+
home_page_url: E.siteUrl,
|
|
1783
|
+
feed_url: f,
|
|
1784
|
+
...y && { next_url: y },
|
|
1785
|
+
description: E.description,
|
|
1786
|
+
author: E.author ? {
|
|
1787
|
+
name: E.author.name,
|
|
1788
|
+
url: E.author.link
|
|
1443
1789
|
} : void 0,
|
|
1444
|
-
items:
|
|
1445
|
-
const
|
|
1446
|
-
id:
|
|
1447
|
-
...
|
|
1790
|
+
items: m.map((g) => {
|
|
1791
|
+
const D = {
|
|
1792
|
+
id: g.id || g.link,
|
|
1793
|
+
...g
|
|
1448
1794
|
// Preserve all dynamic properties
|
|
1449
1795
|
};
|
|
1450
|
-
if (
|
|
1451
|
-
const T =
|
|
1452
|
-
if (
|
|
1796
|
+
if (g.title && (D.title = g.title), g.link && (D.url = g.link), g.content && (D.content_html = g.content), g.description && (D.summary = g.description), (g.date || g.pubDate) && (D.date_published = g.date || g.pubDate), g._imageMetadata && g._hasImage) {
|
|
1797
|
+
const T = g._imageMetadata;
|
|
1798
|
+
if (D.image = T.url, D.attachments || (D.attachments = []), D.attachments.push({
|
|
1453
1799
|
url: T.url,
|
|
1454
1800
|
mime_type: T.mimeType || "image/jpeg",
|
|
1455
1801
|
size_in_bytes: T.size,
|
|
1456
|
-
title:
|
|
1457
|
-
}), T.url &&
|
|
1458
|
-
const
|
|
1459
|
-
|
|
1460
|
-
${
|
|
1802
|
+
title: g.title || "Image"
|
|
1803
|
+
}), T.url && D.content_html && !D.content_html.includes(T.url)) {
|
|
1804
|
+
const M = `<img src="${T.url}" alt="${g.title || ""}"${T.width ? ` width="${T.width}"` : ""}${T.height ? ` height="${T.height}"` : ""} />`;
|
|
1805
|
+
D.content_html = `${M}
|
|
1806
|
+
${D.content_html}`;
|
|
1461
1807
|
}
|
|
1462
1808
|
}
|
|
1463
|
-
return
|
|
1809
|
+
return D;
|
|
1464
1810
|
})
|
|
1465
|
-
}, u =
|
|
1811
|
+
}, u = Ke(l);
|
|
1466
1812
|
return Promise.resolve(typeof u == "string" ? u : JSON.stringify(u));
|
|
1467
1813
|
}
|
|
1468
1814
|
case "rss":
|
|
1469
1815
|
default: {
|
|
1470
|
-
const
|
|
1471
|
-
title:
|
|
1472
|
-
link:
|
|
1473
|
-
description:
|
|
1474
|
-
links:
|
|
1475
|
-
isArchive:
|
|
1476
|
-
language:
|
|
1477
|
-
copyright:
|
|
1478
|
-
webMaster:
|
|
1479
|
-
pubDate:
|
|
1480
|
-
lastBuildDate:
|
|
1481
|
-
items:
|
|
1816
|
+
const y = {
|
|
1817
|
+
title: p,
|
|
1818
|
+
link: E.siteUrl,
|
|
1819
|
+
description: E.description,
|
|
1820
|
+
links: C.length ? C.map((l) => ({ rel: l.rel, href: l.href, type: l.type })) : void 0,
|
|
1821
|
+
isArchive: o ?? !1,
|
|
1822
|
+
language: E.language,
|
|
1823
|
+
copyright: E.copyright,
|
|
1824
|
+
webMaster: E.author?.email,
|
|
1825
|
+
pubDate: w,
|
|
1826
|
+
lastBuildDate: w,
|
|
1827
|
+
items: m.map((l) => {
|
|
1482
1828
|
const u = {
|
|
1483
|
-
...
|
|
1829
|
+
...l
|
|
1484
1830
|
// Preserve all dynamic properties
|
|
1485
1831
|
};
|
|
1486
|
-
if (
|
|
1487
|
-
value:
|
|
1488
|
-
isPermaLink: typeof
|
|
1489
|
-
} :
|
|
1490
|
-
value:
|
|
1491
|
-
isPermaLink: typeof
|
|
1492
|
-
}),
|
|
1493
|
-
const
|
|
1832
|
+
if (l.title && (u.title = l.title), l.link && (u.link = l.link), l.description && (u.description = l.description), (l.date || l.pubDate) && (u.pubDate = l.date || l.pubDate), l.guid ? u.guid = {
|
|
1833
|
+
value: l.guid,
|
|
1834
|
+
isPermaLink: typeof l.guid == "string" && (l.guid.startsWith("http://") || l.guid.startsWith("https://"))
|
|
1835
|
+
} : l.id && (u.guid = {
|
|
1836
|
+
value: l.id,
|
|
1837
|
+
isPermaLink: typeof l.id == "string" && (l.id.startsWith("http://") || l.id.startsWith("https://"))
|
|
1838
|
+
}), l._imageMetadata && l._hasImage) {
|
|
1839
|
+
const g = l._imageMetadata;
|
|
1494
1840
|
u.enclosures = [{
|
|
1495
|
-
url:
|
|
1496
|
-
type:
|
|
1497
|
-
length:
|
|
1841
|
+
url: g.url,
|
|
1842
|
+
type: g.mimeType || "image/jpeg",
|
|
1843
|
+
length: g.size
|
|
1498
1844
|
}];
|
|
1499
|
-
const
|
|
1500
|
-
url:
|
|
1501
|
-
type:
|
|
1845
|
+
const D = {
|
|
1846
|
+
url: g.url,
|
|
1847
|
+
type: g.mimeType || "image/jpeg",
|
|
1502
1848
|
medium: "image"
|
|
1503
1849
|
// image, video, audio, document
|
|
1504
1850
|
};
|
|
1505
|
-
|
|
1851
|
+
g.width && (D.width = g.width), g.height && (D.height = g.height), g.size && (D.fileSize = g.size), g.format && (D.format = g.format), u["media:content"] = [D];
|
|
1506
1852
|
const T = {
|
|
1507
|
-
url:
|
|
1853
|
+
url: g.url
|
|
1508
1854
|
};
|
|
1509
|
-
|
|
1510
|
-
const
|
|
1511
|
-
if (
|
|
1512
|
-
const
|
|
1513
|
-
|
|
1855
|
+
g.width && (T.width = g.width), g.height && (T.height = g.height), u["media:thumbnail"] = [T], l.title && (u["media:title"] = l.title);
|
|
1856
|
+
const M = l.description || l.summary || l.title || "";
|
|
1857
|
+
if (M && (u["media:description"] = M), l.title) {
|
|
1858
|
+
const S = [];
|
|
1859
|
+
l.title && S.push(...l.title.toLowerCase().split(/\s+/).filter((A) => A.length > 3)), l.description && S.push(...l.description.toLowerCase().split(/\s+/).filter((A) => A.length > 3)), S.length > 0 && (u["media:keywords"] = [...new Set(S)].slice(0, 10).join(", "));
|
|
1514
1860
|
}
|
|
1515
|
-
if (
|
|
1516
|
-
value:
|
|
1861
|
+
if (l.authors && Array.isArray(l.authors) && l.authors.length > 0 ? u["media:credit"] = l.authors.map((S) => ({
|
|
1862
|
+
value: S.name || S.displayName || "Unknown",
|
|
1517
1863
|
role: "author"
|
|
1518
|
-
})) :
|
|
1519
|
-
value:
|
|
1864
|
+
})) : E.author && (u["media:credit"] = [{
|
|
1865
|
+
value: E.author.name,
|
|
1520
1866
|
role: "author"
|
|
1521
|
-
}]),
|
|
1867
|
+
}]), E.copyright && (u["media:copyright"] = E.copyright), e && (u["media:category"] = [{
|
|
1522
1868
|
value: e,
|
|
1523
1869
|
scheme: "http://www.schema.org/"
|
|
1524
1870
|
}]), u["media:group"] = [{
|
|
1525
|
-
"media:content": [
|
|
1871
|
+
"media:content": [D],
|
|
1526
1872
|
"media:thumbnail": [T],
|
|
1527
|
-
"media:title":
|
|
1528
|
-
"media:description":
|
|
1529
|
-
}],
|
|
1530
|
-
const
|
|
1531
|
-
u["content:encoded"] = `${
|
|
1532
|
-
${
|
|
1873
|
+
"media:title": l.title || "Untitled",
|
|
1874
|
+
"media:description": M
|
|
1875
|
+
}], g.url && l.content && !l.content.includes(g.url)) {
|
|
1876
|
+
const S = `<img src="${g.url}" alt="${l.title || ""}"${g.width ? ` width="${g.width}"` : ""}${g.height ? ` height="${g.height}"` : ""} />`;
|
|
1877
|
+
u["content:encoded"] = `${S}
|
|
1878
|
+
${l.content}`;
|
|
1533
1879
|
}
|
|
1534
1880
|
}
|
|
1535
|
-
if (!u.enclosures && (
|
|
1536
|
-
const
|
|
1537
|
-
u.enclosures = [{
|
|
1538
|
-
url:
|
|
1881
|
+
if (typeof l.content == "string" && l.content.trim() !== "" && u["content:encoded"] === void 0 && (u["content:encoded"] = l.content), !u.enclosures && (l.feature_image || l.featureImage || l.image)) {
|
|
1882
|
+
const g = l.feature_image || l.featureImage || l.image, D = Ot(g);
|
|
1883
|
+
D && (u.enclosures = [{
|
|
1884
|
+
url: D,
|
|
1539
1885
|
type: "image/jpeg"
|
|
1540
|
-
|
|
1541
|
-
}];
|
|
1886
|
+
}]);
|
|
1542
1887
|
}
|
|
1543
|
-
if (u.dc = {}, (
|
|
1544
|
-
const
|
|
1545
|
-
u.dc.dates || (u.dc.dates = []), u.dc.dates.push(
|
|
1888
|
+
if (u.dc = {}, (l.date || l.pubDate) && (u.dc.date = l.date || l.pubDate), l.timeCreated) {
|
|
1889
|
+
const g = new Date(l.timeCreated * 1e3);
|
|
1890
|
+
u.dc.dates || (u.dc.dates = []), u.dc.dates.push(g);
|
|
1546
1891
|
}
|
|
1547
|
-
return (
|
|
1892
|
+
return (l.seedUid || l.SeedUid) && (u.dc.identifier || (u.dc.identifier = []), u.dc.identifier.push(l.seedUid || l.SeedUid)), (l.storageTransactionId || l.storage_transaction_id) && (u.dc.identifier || (u.dc.identifier = []), u.dc.identifier.push(l.storageTransactionId || l.storage_transaction_id)), (l.import_url || l.importUrl) && (u.dc.source = l.import_url || l.importUrl), (l.seedUid || l.SeedUid) && (u.seedUid = l.seedUid || l.SeedUid), (l.storageTransactionId || l.storage_transaction_id) && (u.storageTransactionId = l.storageTransactionId || l.storage_transaction_id), l.timeCreated && (u.timeCreated = l.timeCreated), u;
|
|
1548
1893
|
})
|
|
1549
1894
|
};
|
|
1550
|
-
return Promise.resolve(
|
|
1895
|
+
return Promise.resolve(Et(y));
|
|
1551
1896
|
}
|
|
1552
1897
|
}
|
|
1553
1898
|
};
|
|
1554
|
-
function
|
|
1555
|
-
switch (
|
|
1899
|
+
function je(t) {
|
|
1900
|
+
switch (t) {
|
|
1556
1901
|
case "atom":
|
|
1557
1902
|
return "application/atom+xml; charset=utf-8";
|
|
1558
1903
|
case "json":
|
|
@@ -1562,16 +1907,16 @@ function De(a) {
|
|
|
1562
1907
|
return "application/rss+xml; charset=utf-8";
|
|
1563
1908
|
}
|
|
1564
1909
|
}
|
|
1565
|
-
function
|
|
1566
|
-
const e =
|
|
1910
|
+
function Be(t) {
|
|
1911
|
+
const e = t.toLowerCase();
|
|
1567
1912
|
return ["rss", "atom", "json"].includes(e) ? e : null;
|
|
1568
1913
|
}
|
|
1569
|
-
function
|
|
1570
|
-
return
|
|
1914
|
+
function Wt(t) {
|
|
1915
|
+
return t.charAt(0).toUpperCase() + t.slice(1);
|
|
1571
1916
|
}
|
|
1572
|
-
async function
|
|
1573
|
-
const
|
|
1574
|
-
if (!
|
|
1917
|
+
async function nn(t, e, n, s, r) {
|
|
1918
|
+
const a = Be(e);
|
|
1919
|
+
if (!a)
|
|
1575
1920
|
return new Response(
|
|
1576
1921
|
JSON.stringify({ error: `Invalid feed format: ${e}` }),
|
|
1577
1922
|
{
|
|
@@ -1579,123 +1924,123 @@ async function ut(a, e, t, o, s) {
|
|
|
1579
1924
|
headers: { "Content-Type": "application/json" }
|
|
1580
1925
|
}
|
|
1581
1926
|
);
|
|
1582
|
-
const
|
|
1583
|
-
console.log(`Schema name: ${
|
|
1584
|
-
const
|
|
1927
|
+
const o = b.singular(t.toLowerCase()), i = b(o), c = G(), d = Math.max(1, r ?? 1), f = c.pageSize, p = (d - 1) * f, w = d > 1 ? { page: d } : void 0;
|
|
1928
|
+
console.log(`Schema name: ${o}`), console.log(`Collection name: ${i}`);
|
|
1929
|
+
const h = Oe(), C = ce();
|
|
1585
1930
|
try {
|
|
1586
|
-
if (
|
|
1587
|
-
const
|
|
1588
|
-
if (
|
|
1589
|
-
return
|
|
1931
|
+
if (C.enabled) {
|
|
1932
|
+
const S = await h.getFeedContent(o, a, w);
|
|
1933
|
+
if (S)
|
|
1934
|
+
return n && Le(n, S.etag) ? (console.log(`Cache hit with ETag match for ${o}:${a} - returning 304`), new Response(null, {
|
|
1590
1935
|
status: 304,
|
|
1591
1936
|
headers: {
|
|
1592
|
-
ETag:
|
|
1593
|
-
"Last-Modified": new Date(
|
|
1937
|
+
ETag: S.etag,
|
|
1938
|
+
"Last-Modified": new Date(S.lastModified * 1e3).toUTCString(),
|
|
1594
1939
|
"Cache-Control": "public, max-age=3600, s-maxage=3600, must-revalidate"
|
|
1595
1940
|
}
|
|
1596
|
-
})) : (console.log(`Cache hit for ${
|
|
1941
|
+
})) : (console.log(`Cache hit for ${o}:${a}`), new Response(S.content, {
|
|
1597
1942
|
status: 200,
|
|
1598
1943
|
headers: {
|
|
1599
|
-
"Content-Type":
|
|
1600
|
-
ETag:
|
|
1601
|
-
"Last-Modified": new Date(
|
|
1944
|
+
"Content-Type": S.contentType,
|
|
1945
|
+
ETag: S.etag,
|
|
1946
|
+
"Last-Modified": new Date(S.lastModified * 1e3).toUTCString(),
|
|
1602
1947
|
"Cache-Control": "public, max-age=3600, s-maxage=3600, must-revalidate",
|
|
1603
|
-
"X-Feed-Schema":
|
|
1604
|
-
"X-Feed-Format":
|
|
1948
|
+
"X-Feed-Schema": o,
|
|
1949
|
+
"X-Feed-Format": a,
|
|
1605
1950
|
"X-Cache": "HIT"
|
|
1606
1951
|
}
|
|
1607
1952
|
}));
|
|
1608
1953
|
}
|
|
1609
|
-
console.log(`Cache miss for ${
|
|
1610
|
-
const
|
|
1611
|
-
const
|
|
1612
|
-
if (
|
|
1613
|
-
const
|
|
1614
|
-
gateways:
|
|
1615
|
-
timeout:
|
|
1954
|
+
console.log(`Cache miss for ${o}:${a} - fetching items`);
|
|
1955
|
+
const m = async () => {
|
|
1956
|
+
const S = await te(o, { limit: f, skip: p });
|
|
1957
|
+
if (C.imageMetadata?.enabled) {
|
|
1958
|
+
const A = new ye({
|
|
1959
|
+
gateways: C.imageMetadata.gateways,
|
|
1960
|
+
timeout: C.imageMetadata.timeout
|
|
1616
1961
|
});
|
|
1617
|
-
return
|
|
1962
|
+
return Ce(S, A, h);
|
|
1618
1963
|
}
|
|
1619
|
-
return
|
|
1620
|
-
},
|
|
1621
|
-
const
|
|
1622
|
-
let
|
|
1623
|
-
if (
|
|
1624
|
-
console.log(`Incremental fetch: last processed timestamp: ${
|
|
1625
|
-
const
|
|
1626
|
-
|
|
1964
|
+
return S;
|
|
1965
|
+
}, y = C.enabled && d === 1 ? await h.withRefreshLock(o, async () => {
|
|
1966
|
+
const S = await h.getFeedData(o);
|
|
1967
|
+
let A;
|
|
1968
|
+
if (S) {
|
|
1969
|
+
console.log(`Incremental fetch: last processed timestamp: ${S.lastProcessedTimestamp}`);
|
|
1970
|
+
const v = await te(o, { limit: f, skip: 0 }), W = h.filterNewItems(v, S.lastProcessedTimestamp);
|
|
1971
|
+
W.length > 0 ? (console.log(`Found ${W.length} new items, merging with ${S.items.length} cached items`), A = h.mergeItems(S.items, W).slice(0, f)) : A = S.items;
|
|
1627
1972
|
} else {
|
|
1628
1973
|
console.log("Cold cache - fetching page 1");
|
|
1629
|
-
const
|
|
1630
|
-
|
|
1974
|
+
const v = await jt();
|
|
1975
|
+
v && console.log(`Client initialized: ${v.isInitialized()}`), A = await te(o, { limit: f, skip: 0 }), console.log(`Found ${A.length} feed items for schema ${o}`);
|
|
1631
1976
|
}
|
|
1632
|
-
if (
|
|
1633
|
-
const
|
|
1634
|
-
gateways:
|
|
1635
|
-
timeout:
|
|
1636
|
-
}),
|
|
1637
|
-
return await
|
|
1977
|
+
if (C.imageMetadata?.enabled) {
|
|
1978
|
+
const v = new ye({
|
|
1979
|
+
gateways: C.imageMetadata.gateways,
|
|
1980
|
+
timeout: C.imageMetadata.timeout
|
|
1981
|
+
}), W = await Ce(A, v, h);
|
|
1982
|
+
return await h.setFeedData(o, A), W;
|
|
1638
1983
|
}
|
|
1639
|
-
return await
|
|
1640
|
-
}) : await
|
|
1984
|
+
return await h.setFeedData(o, A), A;
|
|
1985
|
+
}) : await m(), l = `${E.feedUrl}/${i}/${a}`, u = y.length === f, g = [];
|
|
1641
1986
|
if (d === 1) {
|
|
1642
|
-
const
|
|
1643
|
-
|
|
1987
|
+
const S = /* @__PURE__ */ new Date(), A = new Date(S.getFullYear(), S.getMonth() - 1, 1);
|
|
1988
|
+
g.push({
|
|
1644
1989
|
rel: "prev-archive",
|
|
1645
|
-
href: `${
|
|
1990
|
+
href: `${E.feedUrl}/${i}/archive/${A.getFullYear()}/${A.getMonth() + 1}/${a}`
|
|
1646
1991
|
});
|
|
1647
1992
|
}
|
|
1648
|
-
const
|
|
1649
|
-
|
|
1650
|
-
n,
|
|
1651
|
-
r,
|
|
1993
|
+
const T = await Ne(
|
|
1994
|
+
y,
|
|
1652
1995
|
o,
|
|
1996
|
+
a,
|
|
1997
|
+
s,
|
|
1653
1998
|
{
|
|
1654
1999
|
page: d,
|
|
1655
2000
|
pageSize: f,
|
|
1656
|
-
hasNext:
|
|
1657
|
-
baseUrl:
|
|
2001
|
+
hasNext: u,
|
|
2002
|
+
baseUrl: l
|
|
1658
2003
|
},
|
|
1659
|
-
|
|
2004
|
+
g.length ? g : void 0,
|
|
1660
2005
|
!1
|
|
1661
|
-
),
|
|
1662
|
-
if (
|
|
1663
|
-
await
|
|
1664
|
-
const
|
|
1665
|
-
return new Response(
|
|
2006
|
+
), M = je(a);
|
|
2007
|
+
if (C.enabled) {
|
|
2008
|
+
await h.setFeedContent(o, a, T, M, w);
|
|
2009
|
+
const S = await h.getFeedContent(o, a, w), A = S?.etag || "", v = S?.lastModified || Math.floor(Date.now() / 1e3);
|
|
2010
|
+
return new Response(T, {
|
|
1666
2011
|
status: 200,
|
|
1667
2012
|
headers: {
|
|
1668
|
-
"Content-Type":
|
|
1669
|
-
ETag:
|
|
1670
|
-
"Last-Modified": new Date(
|
|
2013
|
+
"Content-Type": M,
|
|
2014
|
+
ETag: A,
|
|
2015
|
+
"Last-Modified": new Date(v * 1e3).toUTCString(),
|
|
1671
2016
|
"Cache-Control": "public, max-age=3600, s-maxage=3600, must-revalidate",
|
|
1672
|
-
"X-Feed-Schema":
|
|
1673
|
-
"X-Feed-Format":
|
|
2017
|
+
"X-Feed-Schema": o,
|
|
2018
|
+
"X-Feed-Format": a,
|
|
1674
2019
|
"X-Cache": "MISS"
|
|
1675
2020
|
}
|
|
1676
2021
|
});
|
|
1677
2022
|
}
|
|
1678
|
-
return new Response(
|
|
2023
|
+
return new Response(T, {
|
|
1679
2024
|
status: 200,
|
|
1680
2025
|
headers: {
|
|
1681
|
-
"Content-Type":
|
|
2026
|
+
"Content-Type": M,
|
|
1682
2027
|
"Cache-Control": "public, max-age=3600, s-maxage=3600",
|
|
1683
|
-
"X-Feed-Schema":
|
|
1684
|
-
"X-Feed-Format":
|
|
2028
|
+
"X-Feed-Schema": o,
|
|
2029
|
+
"X-Feed-Format": a
|
|
1685
2030
|
}
|
|
1686
2031
|
});
|
|
1687
|
-
} catch (
|
|
1688
|
-
if (console.error("Feed generation error:",
|
|
1689
|
-
const
|
|
1690
|
-
if (
|
|
1691
|
-
return console.log("Serving stale cache due to error"), new Response(
|
|
2032
|
+
} catch (m) {
|
|
2033
|
+
if (console.error("Feed generation error:", m), C.enabled) {
|
|
2034
|
+
const y = await h.getFeedContent(o, a, w);
|
|
2035
|
+
if (y)
|
|
2036
|
+
return console.log("Serving stale cache due to error"), new Response(y.content, {
|
|
1692
2037
|
status: 200,
|
|
1693
2038
|
headers: {
|
|
1694
|
-
"Content-Type":
|
|
1695
|
-
ETag:
|
|
2039
|
+
"Content-Type": y.contentType,
|
|
2040
|
+
ETag: y.etag,
|
|
1696
2041
|
"Cache-Control": "public, max-age=3600, s-maxage=3600, must-revalidate",
|
|
1697
|
-
"X-Feed-Schema":
|
|
1698
|
-
"X-Feed-Format":
|
|
2042
|
+
"X-Feed-Schema": o,
|
|
2043
|
+
"X-Feed-Format": a,
|
|
1699
2044
|
"X-Cache": "STALE",
|
|
1700
2045
|
Warning: '299 - "Cache is stale"'
|
|
1701
2046
|
}
|
|
@@ -1704,7 +2049,7 @@ async function ut(a, e, t, o, s) {
|
|
|
1704
2049
|
return new Response(
|
|
1705
2050
|
JSON.stringify({
|
|
1706
2051
|
error: "Failed to generate feed",
|
|
1707
|
-
message:
|
|
2052
|
+
message: m instanceof Error ? m.message : "Unknown error"
|
|
1708
2053
|
}),
|
|
1709
2054
|
{
|
|
1710
2055
|
status: 500,
|
|
@@ -1713,107 +2058,119 @@ async function ut(a, e, t, o, s) {
|
|
|
1713
2058
|
);
|
|
1714
2059
|
}
|
|
1715
2060
|
}
|
|
1716
|
-
async function
|
|
2061
|
+
async function rn(t, e, n, s, r, a) {
|
|
1717
2062
|
if (e < 1970 || e > 2100)
|
|
1718
2063
|
return new Response(
|
|
1719
2064
|
JSON.stringify({ error: `Invalid year: ${e}` }),
|
|
1720
2065
|
{ status: 400, headers: { "Content-Type": "application/json" } }
|
|
1721
2066
|
);
|
|
1722
|
-
if (
|
|
2067
|
+
if (n < 1 || n > 12)
|
|
1723
2068
|
return new Response(
|
|
1724
|
-
JSON.stringify({ error: `Invalid month: ${
|
|
2069
|
+
JSON.stringify({ error: `Invalid month: ${n}` }),
|
|
1725
2070
|
{ status: 400, headers: { "Content-Type": "application/json" } }
|
|
1726
2071
|
);
|
|
1727
|
-
const
|
|
1728
|
-
if (!
|
|
2072
|
+
const o = Be(s);
|
|
2073
|
+
if (!o)
|
|
1729
2074
|
return new Response(
|
|
1730
|
-
JSON.stringify({ error: `Invalid feed format: ${
|
|
2075
|
+
JSON.stringify({ error: `Invalid feed format: ${s}` }),
|
|
1731
2076
|
{ status: 400, headers: { "Content-Type": "application/json" } }
|
|
1732
2077
|
);
|
|
1733
|
-
const i =
|
|
2078
|
+
const i = b.singular(t.toLowerCase()), c = b(i), d = { archive: { year: e, month: n } }, f = Oe(), p = ce();
|
|
1734
2079
|
try {
|
|
1735
2080
|
if (p.enabled) {
|
|
1736
|
-
const
|
|
1737
|
-
if (
|
|
1738
|
-
return
|
|
2081
|
+
const T = await f.getFeedContent(i, o, d);
|
|
2082
|
+
if (T)
|
|
2083
|
+
return r && Le(r, T.etag) ? new Response(null, {
|
|
1739
2084
|
status: 304,
|
|
1740
2085
|
headers: {
|
|
1741
|
-
ETag:
|
|
1742
|
-
"Last-Modified": new Date(
|
|
2086
|
+
ETag: T.etag,
|
|
2087
|
+
"Last-Modified": new Date(T.lastModified * 1e3).toUTCString(),
|
|
1743
2088
|
"Cache-Control": "public, max-age=86400, s-maxage=86400, must-revalidate"
|
|
1744
2089
|
}
|
|
1745
|
-
}) : new Response(
|
|
2090
|
+
}) : new Response(T.content, {
|
|
1746
2091
|
status: 200,
|
|
1747
2092
|
headers: {
|
|
1748
|
-
"Content-Type":
|
|
1749
|
-
ETag:
|
|
1750
|
-
"Last-Modified": new Date(
|
|
2093
|
+
"Content-Type": T.contentType,
|
|
2094
|
+
ETag: T.etag,
|
|
2095
|
+
"Last-Modified": new Date(T.lastModified * 1e3).toUTCString(),
|
|
1751
2096
|
"Cache-Control": "public, max-age=86400, s-maxage=86400, must-revalidate",
|
|
1752
2097
|
"X-Feed-Schema": i,
|
|
1753
|
-
"X-Feed-Format":
|
|
2098
|
+
"X-Feed-Format": o,
|
|
1754
2099
|
"X-Cache": "HIT"
|
|
1755
2100
|
}
|
|
1756
2101
|
});
|
|
1757
2102
|
}
|
|
1758
|
-
const
|
|
1759
|
-
{ rel: "prev-archive", href: `${
|
|
1760
|
-
{ rel: "current", href:
|
|
1761
|
-
],
|
|
1762
|
-
(
|
|
1763
|
-
const
|
|
1764
|
-
|
|
2103
|
+
const w = await mt(i, e, n), h = `${E.feedUrl}/${c}/${o}`, C = `${E.feedUrl}/${c}/archive`, m = [
|
|
2104
|
+
{ rel: "prev-archive", href: `${C}/${n === 1 ? e - 1 : e}/${n === 1 ? 12 : n - 1}/${o}` },
|
|
2105
|
+
{ rel: "current", href: h }
|
|
2106
|
+
], y = n === 12 ? e + 1 : e, l = n === 12 ? 1 : n + 1, u = /* @__PURE__ */ new Date();
|
|
2107
|
+
(y < u.getFullYear() || y === u.getFullYear() && l <= u.getMonth() + 1) && m.push({ rel: "next-archive", href: `${C}/${y}/${l}/${o}` });
|
|
2108
|
+
const g = await Ne(
|
|
2109
|
+
w,
|
|
1765
2110
|
i,
|
|
1766
|
-
|
|
1767
|
-
|
|
2111
|
+
o,
|
|
2112
|
+
a,
|
|
1768
2113
|
void 0,
|
|
1769
|
-
|
|
2114
|
+
m,
|
|
1770
2115
|
!0
|
|
1771
|
-
),
|
|
2116
|
+
), D = je(o);
|
|
1772
2117
|
if (p.enabled) {
|
|
1773
|
-
await f.setFeedContent(i,
|
|
1774
|
-
const
|
|
1775
|
-
return new Response(
|
|
2118
|
+
await f.setFeedContent(i, o, g, D, d);
|
|
2119
|
+
const T = await f.getFeedContent(i, o, d), M = T?.etag || "", S = T?.lastModified || Math.floor(Date.now() / 1e3);
|
|
2120
|
+
return new Response(g, {
|
|
1776
2121
|
status: 200,
|
|
1777
2122
|
headers: {
|
|
1778
|
-
"Content-Type":
|
|
1779
|
-
ETag:
|
|
1780
|
-
"Last-Modified": new Date(
|
|
2123
|
+
"Content-Type": D,
|
|
2124
|
+
ETag: M,
|
|
2125
|
+
"Last-Modified": new Date(S * 1e3).toUTCString(),
|
|
1781
2126
|
"Cache-Control": "public, max-age=86400, s-maxage=86400, must-revalidate",
|
|
1782
2127
|
"X-Feed-Schema": i,
|
|
1783
|
-
"X-Feed-Format":
|
|
2128
|
+
"X-Feed-Format": o,
|
|
1784
2129
|
"X-Cache": "MISS"
|
|
1785
2130
|
}
|
|
1786
2131
|
});
|
|
1787
2132
|
}
|
|
1788
|
-
return new Response(
|
|
2133
|
+
return new Response(g, {
|
|
1789
2134
|
status: 200,
|
|
1790
2135
|
headers: {
|
|
1791
|
-
"Content-Type":
|
|
2136
|
+
"Content-Type": D,
|
|
1792
2137
|
"Cache-Control": "public, max-age=86400, s-maxage=86400",
|
|
1793
2138
|
"X-Feed-Schema": i,
|
|
1794
|
-
"X-Feed-Format":
|
|
2139
|
+
"X-Feed-Format": o
|
|
1795
2140
|
}
|
|
1796
2141
|
});
|
|
1797
|
-
} catch (
|
|
1798
|
-
return console.error("Archive feed generation error:",
|
|
2142
|
+
} catch (w) {
|
|
2143
|
+
return console.error("Archive feed generation error:", w), new Response(
|
|
1799
2144
|
JSON.stringify({
|
|
1800
2145
|
error: "Failed to generate archive feed",
|
|
1801
|
-
message:
|
|
2146
|
+
message: w instanceof Error ? w.message : "Unknown error"
|
|
1802
2147
|
}),
|
|
1803
2148
|
{ status: 500, headers: { "Content-Type": "application/json" } }
|
|
1804
2149
|
);
|
|
1805
2150
|
}
|
|
1806
2151
|
}
|
|
1807
2152
|
export {
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
2153
|
+
nt as FEED_RICH_BODY_STORAGE_SCHEMAS,
|
|
2154
|
+
on as classifyMediaRef,
|
|
2155
|
+
Ne as createFeed,
|
|
2156
|
+
tt as enrichImageSeedCloneForFeed,
|
|
2157
|
+
Pt as feedItemRichTextContainsDataUriImage,
|
|
2158
|
+
Rt as filterItemsByRichTextDataUriImagePolicy,
|
|
2159
|
+
jt as getClient,
|
|
2160
|
+
cn as getFeedItemStringField,
|
|
2161
|
+
te as getFeedItemsBySchemaName,
|
|
2162
|
+
mt as getFeedItemsBySchemaNameForMonth,
|
|
2163
|
+
rn as handleArchiveFeedRequest,
|
|
2164
|
+
nn as handleFeedRequest,
|
|
2165
|
+
Nt as initializeSeedClient,
|
|
2166
|
+
B as isFeedRichBodyStorageSchema,
|
|
2167
|
+
G as loadFeedConfig,
|
|
2168
|
+
ln as normalizeFeedItemFields,
|
|
2169
|
+
Qt as parseRssString,
|
|
2170
|
+
xt as pickFeedItemContent,
|
|
2171
|
+
kt as pickFeedItemDescription,
|
|
2172
|
+
en as resetCacheManager,
|
|
2173
|
+
dn as resolveMediaRef,
|
|
2174
|
+
tn as teardownSeedClient
|
|
1818
2175
|
};
|
|
1819
2176
|
//# sourceMappingURL=index.js.map
|