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