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