@agenticmail/enterprise 0.5.435 → 0.5.437
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/dist/agent-tools-IP5323GZ.js +22116 -0
- package/dist/agent-tools-M3V5KU65.js +22115 -0
- package/dist/agent-tools-SXVLYL26.js +22112 -0
- package/dist/chunk-2HYM6JPH.js +4993 -0
- package/dist/chunk-3XCVZMSU.js +5621 -0
- package/dist/chunk-HUFSY23L.js +4993 -0
- package/dist/chunk-IXPUS3QJ.js +1728 -0
- package/dist/chunk-KBWQNT65.js +1728 -0
- package/dist/chunk-KUKWAN57.js +227 -0
- package/dist/chunk-KYRVUWKD.js +4993 -0
- package/dist/chunk-LT4V6FK2.js +1728 -0
- package/dist/chunk-OG5W2INR.js +5621 -0
- package/dist/chunk-SVLHVBIB.js +245 -0
- package/dist/chunk-T34AHJ26.js +177 -0
- package/dist/chunk-V3ZCRI2I.js +5621 -0
- package/dist/cli-agent-CVXIAL7M.js +2715 -0
- package/dist/cli-agent-IWJ6A4DI.js +2715 -0
- package/dist/cli-agent-LT3FP3TE.js +2715 -0
- package/dist/cli-serve-LNZ6EPJE.js +286 -0
- package/dist/cli-serve-QR4OHYOT.js +286 -0
- package/dist/cli-serve-UPG5NOWU.js +286 -0
- package/dist/cli.js +3 -3
- package/dist/index.js +3 -3
- package/dist/polymarket-shared-4DPFKDXJ.js +49 -0
- package/dist/polymarket-shared-6CKB3KE3.js +37 -0
- package/dist/polymarket-shared-LBYAEK7W.js +53 -0
- package/dist/runtime-OENVV225.js +46 -0
- package/dist/runtime-TS5ASW2O.js +46 -0
- package/dist/runtime-XEWMQT4S.js +46 -0
- package/dist/server-4H5XVZ3N.js +28 -0
- package/dist/server-SB3YD5SK.js +28 -0
- package/dist/server-XLDIMRJM.js +28 -0
- package/dist/setup-EZ7Z4ZZK.js +20 -0
- package/dist/setup-GYFWXTJU.js +20 -0
- package/dist/setup-KH3SGVNP.js +20 -0
- package/logs/cloudflared-error.log +20 -0
- package/logs/john-error.log +2 -0
- package/package.json +1 -1
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
// src/agent-tools/tools/polymarket-shared.ts
|
|
2
|
+
var _dialect = "sqlite";
|
|
3
|
+
function setDialect(d) {
|
|
4
|
+
_dialect = d;
|
|
5
|
+
}
|
|
6
|
+
function getDialect() {
|
|
7
|
+
return _dialect;
|
|
8
|
+
}
|
|
9
|
+
function setPostgresFlag(v) {
|
|
10
|
+
_dialect = v ? "postgres" : "sqlite";
|
|
11
|
+
}
|
|
12
|
+
function autoId() {
|
|
13
|
+
switch (_dialect) {
|
|
14
|
+
case "postgres":
|
|
15
|
+
return "SERIAL PRIMARY KEY";
|
|
16
|
+
case "mysql":
|
|
17
|
+
return "INTEGER PRIMARY KEY AUTO_INCREMENT";
|
|
18
|
+
default:
|
|
19
|
+
return "INTEGER PRIMARY KEY";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function timestampDefault() {
|
|
23
|
+
switch (_dialect) {
|
|
24
|
+
case "postgres":
|
|
25
|
+
return "TIMESTAMP DEFAULT NOW()";
|
|
26
|
+
case "mysql":
|
|
27
|
+
return "TIMESTAMP DEFAULT CURRENT_TIMESTAMP";
|
|
28
|
+
default:
|
|
29
|
+
return "TIMESTAMP DEFAULT CURRENT_TIMESTAMP";
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function jsonType() {
|
|
33
|
+
return _dialect === "postgres" ? "JSONB" : "TEXT";
|
|
34
|
+
}
|
|
35
|
+
function boolVal(v) {
|
|
36
|
+
if (_dialect === "postgres") return v ? "TRUE" : "FALSE";
|
|
37
|
+
return v ? "1" : "0";
|
|
38
|
+
}
|
|
39
|
+
function insertOrReplace(table, cols, conflictCol, updateCols) {
|
|
40
|
+
const placeholders = cols.map(() => "?").join(", ");
|
|
41
|
+
const colList = cols.join(", ");
|
|
42
|
+
if (_dialect === "mysql") {
|
|
43
|
+
return `REPLACE INTO ${table} (${colList}) VALUES (${placeholders})`;
|
|
44
|
+
}
|
|
45
|
+
const updates = (updateCols || cols.filter((c) => c !== conflictCol)).map((c) => `${c} = EXCLUDED.${c}`).join(", ");
|
|
46
|
+
return `INSERT INTO ${table} (${colList}) VALUES (${placeholders}) ON CONFLICT(${conflictCol}) DO UPDATE SET ${updates}`;
|
|
47
|
+
}
|
|
48
|
+
function insertOrIgnore(table, cols) {
|
|
49
|
+
const placeholders = cols.map(() => "?").join(", ");
|
|
50
|
+
const colList = cols.join(", ");
|
|
51
|
+
if (_dialect === "mysql") return `INSERT IGNORE INTO ${table} (${colList}) VALUES (${placeholders})`;
|
|
52
|
+
if (_dialect === "postgres") return `INSERT INTO ${table} (${colList}) VALUES (${placeholders}) ON CONFLICT DO NOTHING`;
|
|
53
|
+
return `INSERT OR IGNORE INTO ${table} (${colList}) VALUES (${placeholders})`;
|
|
54
|
+
}
|
|
55
|
+
async function detectDialect(db) {
|
|
56
|
+
try {
|
|
57
|
+
await db.execute(`SELECT NOW()`);
|
|
58
|
+
return "postgres";
|
|
59
|
+
} catch {
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
const r = await db.execute(`SELECT VERSION() as v`);
|
|
63
|
+
const ver = r?.rows?.[0]?.v || r?.[0]?.v || "";
|
|
64
|
+
if (/mysql|maria/i.test(String(ver))) return "mysql";
|
|
65
|
+
} catch {
|
|
66
|
+
}
|
|
67
|
+
return "sqlite";
|
|
68
|
+
}
|
|
69
|
+
var responseCache = /* @__PURE__ */ new Map();
|
|
70
|
+
var MAX_CACHE_ENTRIES = 500;
|
|
71
|
+
function getCached(key, ttlMs) {
|
|
72
|
+
const entry = responseCache.get(key);
|
|
73
|
+
if (entry && Date.now() - entry.ts < ttlMs) return entry.data;
|
|
74
|
+
if (entry) responseCache.delete(key);
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
function setCache(key, data) {
|
|
78
|
+
if (responseCache.size > MAX_CACHE_ENTRIES) {
|
|
79
|
+
const oldest = responseCache.keys().next().value;
|
|
80
|
+
if (oldest) responseCache.delete(oldest);
|
|
81
|
+
}
|
|
82
|
+
responseCache.set(key, { data, ts: Date.now() });
|
|
83
|
+
}
|
|
84
|
+
var rateLimits = /* @__PURE__ */ new Map();
|
|
85
|
+
var RATE_WINDOW_MS = 6e4;
|
|
86
|
+
var MAX_REQUESTS_PER_MINUTE = 30;
|
|
87
|
+
function checkRateLimit(domain) {
|
|
88
|
+
const now = Date.now();
|
|
89
|
+
const times = rateLimits.get(domain) || [];
|
|
90
|
+
const recent = times.filter((t) => now - t < RATE_WINDOW_MS);
|
|
91
|
+
if (recent.length >= MAX_REQUESTS_PER_MINUTE) return false;
|
|
92
|
+
recent.push(now);
|
|
93
|
+
rateLimits.set(domain, recent);
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
async function cachedFetchJSON(url, cacheTtlMs = 3e4, timeout = 1e4) {
|
|
97
|
+
const cached = getCached(url, cacheTtlMs);
|
|
98
|
+
if (cached !== null) return cached;
|
|
99
|
+
const domain = new URL(url).hostname;
|
|
100
|
+
if (!checkRateLimit(domain)) {
|
|
101
|
+
throw new Error(`Rate limited: too many requests to ${domain}. Wait a moment.`);
|
|
102
|
+
}
|
|
103
|
+
const controller = new AbortController();
|
|
104
|
+
const timer = setTimeout(() => controller.abort(), timeout);
|
|
105
|
+
try {
|
|
106
|
+
const res = await fetch(url, { signal: controller.signal });
|
|
107
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`);
|
|
108
|
+
const data = await res.json();
|
|
109
|
+
setCache(url, data);
|
|
110
|
+
return data;
|
|
111
|
+
} catch (e) {
|
|
112
|
+
if (e.name === "AbortError") throw new Error(`Request to ${domain} timed out after ${timeout}ms`);
|
|
113
|
+
throw e;
|
|
114
|
+
} finally {
|
|
115
|
+
clearTimeout(timer);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
async function cachedFetchText(url, cacheTtlMs = 6e4, timeout = 1e4) {
|
|
119
|
+
const cached = getCached("txt:" + url, cacheTtlMs);
|
|
120
|
+
if (cached !== null) return cached;
|
|
121
|
+
const domain = new URL(url).hostname;
|
|
122
|
+
if (!checkRateLimit(domain)) {
|
|
123
|
+
throw new Error(`Rate limited: too many requests to ${domain}. Wait a moment.`);
|
|
124
|
+
}
|
|
125
|
+
const controller = new AbortController();
|
|
126
|
+
const timer = setTimeout(() => controller.abort(), timeout);
|
|
127
|
+
try {
|
|
128
|
+
const res = await fetch(url, { signal: controller.signal, headers: { "User-Agent": "PolymarketBot/1.0" } });
|
|
129
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
130
|
+
const text = await res.text();
|
|
131
|
+
setCache("txt:" + url, text);
|
|
132
|
+
return text;
|
|
133
|
+
} catch (e) {
|
|
134
|
+
if (e.name === "AbortError") throw new Error(`Request to ${domain} timed out after ${timeout}ms`);
|
|
135
|
+
throw e;
|
|
136
|
+
} finally {
|
|
137
|
+
clearTimeout(timer);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function validateTokenId(tokenId) {
|
|
141
|
+
if (!tokenId || typeof tokenId !== "string") return null;
|
|
142
|
+
const trimmed = tokenId.trim();
|
|
143
|
+
if (trimmed.length < 5) return null;
|
|
144
|
+
return trimmed;
|
|
145
|
+
}
|
|
146
|
+
function validateAddress(addr) {
|
|
147
|
+
if (!addr || typeof addr !== "string") return null;
|
|
148
|
+
const trimmed = addr.trim().toLowerCase();
|
|
149
|
+
if (!/^0x[a-f0-9]{40}$/i.test(trimmed) && trimmed.length < 10) return null;
|
|
150
|
+
return trimmed;
|
|
151
|
+
}
|
|
152
|
+
function validateSlug(slug) {
|
|
153
|
+
if (!slug || typeof slug !== "string") return null;
|
|
154
|
+
return slug.trim();
|
|
155
|
+
}
|
|
156
|
+
function clampNumber(val, min, max, defaultVal) {
|
|
157
|
+
const n = typeof val === "number" ? val : parseFloat(val);
|
|
158
|
+
if (isNaN(n)) return defaultVal;
|
|
159
|
+
return Math.max(min, Math.min(max, n));
|
|
160
|
+
}
|
|
161
|
+
function safeDbExec(db, sql, ...args) {
|
|
162
|
+
if (!db) return null;
|
|
163
|
+
try {
|
|
164
|
+
if (args.length > 0) {
|
|
165
|
+
return db.prepare?.(sql)?.run(...args);
|
|
166
|
+
}
|
|
167
|
+
return db.exec?.(sql);
|
|
168
|
+
} catch {
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
function safeDbQuery(db, sql, ...args) {
|
|
173
|
+
if (!db) return [];
|
|
174
|
+
try {
|
|
175
|
+
return db.prepare?.(sql)?.all(...args) || [];
|
|
176
|
+
} catch {
|
|
177
|
+
return [];
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
function safeDbGet(db, sql, ...args) {
|
|
181
|
+
if (!db) return null;
|
|
182
|
+
try {
|
|
183
|
+
return db.prepare?.(sql)?.get(...args) || null;
|
|
184
|
+
} catch {
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
function parseRSSItems(xml) {
|
|
189
|
+
const items = [];
|
|
190
|
+
const itemRegex = /<item>([\s\S]*?)<\/item>/g;
|
|
191
|
+
let match;
|
|
192
|
+
while ((match = itemRegex.exec(xml)) !== null) {
|
|
193
|
+
const get = (tag) => {
|
|
194
|
+
const m = match[1].match(new RegExp(`<${tag}[^>]*>([\\s\\S]*?)<\\/${tag}>`));
|
|
195
|
+
return m ? m[1].replace(/<!\[CDATA\[|\]\]>/g, "").trim() : "";
|
|
196
|
+
};
|
|
197
|
+
items.push({
|
|
198
|
+
title: get("title"),
|
|
199
|
+
link: get("link"),
|
|
200
|
+
pubDate: get("pubDate"),
|
|
201
|
+
description: get("description").replace(/<[^>]+>/g, "").slice(0, 300),
|
|
202
|
+
source: get("source")
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
return items;
|
|
206
|
+
}
|
|
207
|
+
async function withRetry(fn, retries = 2, delayMs = 1e3) {
|
|
208
|
+
let lastError;
|
|
209
|
+
for (let i = 0; i <= retries; i++) {
|
|
210
|
+
try {
|
|
211
|
+
return await fn();
|
|
212
|
+
} catch (e) {
|
|
213
|
+
lastError = e;
|
|
214
|
+
if (i < retries) await new Promise((r) => setTimeout(r, delayMs * (i + 1)));
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
throw lastError;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export {
|
|
221
|
+
setDialect,
|
|
222
|
+
getDialect,
|
|
223
|
+
setPostgresFlag,
|
|
224
|
+
autoId,
|
|
225
|
+
timestampDefault,
|
|
226
|
+
jsonType,
|
|
227
|
+
boolVal,
|
|
228
|
+
insertOrReplace,
|
|
229
|
+
insertOrIgnore,
|
|
230
|
+
detectDialect,
|
|
231
|
+
getCached,
|
|
232
|
+
setCache,
|
|
233
|
+
checkRateLimit,
|
|
234
|
+
cachedFetchJSON,
|
|
235
|
+
cachedFetchText,
|
|
236
|
+
validateTokenId,
|
|
237
|
+
validateAddress,
|
|
238
|
+
validateSlug,
|
|
239
|
+
clampNumber,
|
|
240
|
+
safeDbExec,
|
|
241
|
+
safeDbQuery,
|
|
242
|
+
safeDbGet,
|
|
243
|
+
parseRSSItems,
|
|
244
|
+
withRetry
|
|
245
|
+
};
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
// src/agent-tools/tools/polymarket-shared.ts
|
|
2
|
+
var _pgFlag = false;
|
|
3
|
+
function setPostgresFlag(v) {
|
|
4
|
+
_pgFlag = v;
|
|
5
|
+
}
|
|
6
|
+
function autoId() {
|
|
7
|
+
return _pgFlag ? "SERIAL PRIMARY KEY" : "INTEGER PRIMARY KEY";
|
|
8
|
+
}
|
|
9
|
+
var responseCache = /* @__PURE__ */ new Map();
|
|
10
|
+
var MAX_CACHE_ENTRIES = 500;
|
|
11
|
+
function getCached(key, ttlMs) {
|
|
12
|
+
const entry = responseCache.get(key);
|
|
13
|
+
if (entry && Date.now() - entry.ts < ttlMs) return entry.data;
|
|
14
|
+
if (entry) responseCache.delete(key);
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
function setCache(key, data) {
|
|
18
|
+
if (responseCache.size > MAX_CACHE_ENTRIES) {
|
|
19
|
+
const oldest = responseCache.keys().next().value;
|
|
20
|
+
if (oldest) responseCache.delete(oldest);
|
|
21
|
+
}
|
|
22
|
+
responseCache.set(key, { data, ts: Date.now() });
|
|
23
|
+
}
|
|
24
|
+
var rateLimits = /* @__PURE__ */ new Map();
|
|
25
|
+
var RATE_WINDOW_MS = 6e4;
|
|
26
|
+
var MAX_REQUESTS_PER_MINUTE = 30;
|
|
27
|
+
function checkRateLimit(domain) {
|
|
28
|
+
const now = Date.now();
|
|
29
|
+
const times = rateLimits.get(domain) || [];
|
|
30
|
+
const recent = times.filter((t) => now - t < RATE_WINDOW_MS);
|
|
31
|
+
if (recent.length >= MAX_REQUESTS_PER_MINUTE) return false;
|
|
32
|
+
recent.push(now);
|
|
33
|
+
rateLimits.set(domain, recent);
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
async function cachedFetchJSON(url, cacheTtlMs = 3e4, timeout = 1e4) {
|
|
37
|
+
const cached = getCached(url, cacheTtlMs);
|
|
38
|
+
if (cached !== null) return cached;
|
|
39
|
+
const domain = new URL(url).hostname;
|
|
40
|
+
if (!checkRateLimit(domain)) {
|
|
41
|
+
throw new Error(`Rate limited: too many requests to ${domain}. Wait a moment.`);
|
|
42
|
+
}
|
|
43
|
+
const controller = new AbortController();
|
|
44
|
+
const timer = setTimeout(() => controller.abort(), timeout);
|
|
45
|
+
try {
|
|
46
|
+
const res = await fetch(url, { signal: controller.signal });
|
|
47
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`);
|
|
48
|
+
const data = await res.json();
|
|
49
|
+
setCache(url, data);
|
|
50
|
+
return data;
|
|
51
|
+
} catch (e) {
|
|
52
|
+
if (e.name === "AbortError") throw new Error(`Request to ${domain} timed out after ${timeout}ms`);
|
|
53
|
+
throw e;
|
|
54
|
+
} finally {
|
|
55
|
+
clearTimeout(timer);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async function cachedFetchText(url, cacheTtlMs = 6e4, timeout = 1e4) {
|
|
59
|
+
const cached = getCached("txt:" + url, cacheTtlMs);
|
|
60
|
+
if (cached !== null) return cached;
|
|
61
|
+
const domain = new URL(url).hostname;
|
|
62
|
+
if (!checkRateLimit(domain)) {
|
|
63
|
+
throw new Error(`Rate limited: too many requests to ${domain}. Wait a moment.`);
|
|
64
|
+
}
|
|
65
|
+
const controller = new AbortController();
|
|
66
|
+
const timer = setTimeout(() => controller.abort(), timeout);
|
|
67
|
+
try {
|
|
68
|
+
const res = await fetch(url, { signal: controller.signal, headers: { "User-Agent": "PolymarketBot/1.0" } });
|
|
69
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
70
|
+
const text = await res.text();
|
|
71
|
+
setCache("txt:" + url, text);
|
|
72
|
+
return text;
|
|
73
|
+
} catch (e) {
|
|
74
|
+
if (e.name === "AbortError") throw new Error(`Request to ${domain} timed out after ${timeout}ms`);
|
|
75
|
+
throw e;
|
|
76
|
+
} finally {
|
|
77
|
+
clearTimeout(timer);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function validateTokenId(tokenId) {
|
|
81
|
+
if (!tokenId || typeof tokenId !== "string") return null;
|
|
82
|
+
const trimmed = tokenId.trim();
|
|
83
|
+
if (trimmed.length < 5) return null;
|
|
84
|
+
return trimmed;
|
|
85
|
+
}
|
|
86
|
+
function validateAddress(addr) {
|
|
87
|
+
if (!addr || typeof addr !== "string") return null;
|
|
88
|
+
const trimmed = addr.trim().toLowerCase();
|
|
89
|
+
if (!/^0x[a-f0-9]{40}$/i.test(trimmed) && trimmed.length < 10) return null;
|
|
90
|
+
return trimmed;
|
|
91
|
+
}
|
|
92
|
+
function validateSlug(slug) {
|
|
93
|
+
if (!slug || typeof slug !== "string") return null;
|
|
94
|
+
return slug.trim();
|
|
95
|
+
}
|
|
96
|
+
function clampNumber(val, min, max, defaultVal) {
|
|
97
|
+
const n = typeof val === "number" ? val : parseFloat(val);
|
|
98
|
+
if (isNaN(n)) return defaultVal;
|
|
99
|
+
return Math.max(min, Math.min(max, n));
|
|
100
|
+
}
|
|
101
|
+
function safeDbExec(db, sql, ...args) {
|
|
102
|
+
if (!db) return null;
|
|
103
|
+
try {
|
|
104
|
+
if (args.length > 0) {
|
|
105
|
+
return db.prepare?.(sql)?.run(...args);
|
|
106
|
+
}
|
|
107
|
+
return db.exec?.(sql);
|
|
108
|
+
} catch {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function safeDbQuery(db, sql, ...args) {
|
|
113
|
+
if (!db) return [];
|
|
114
|
+
try {
|
|
115
|
+
return db.prepare?.(sql)?.all(...args) || [];
|
|
116
|
+
} catch {
|
|
117
|
+
return [];
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
function safeDbGet(db, sql, ...args) {
|
|
121
|
+
if (!db) return null;
|
|
122
|
+
try {
|
|
123
|
+
return db.prepare?.(sql)?.get(...args) || null;
|
|
124
|
+
} catch {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
function parseRSSItems(xml) {
|
|
129
|
+
const items = [];
|
|
130
|
+
const itemRegex = /<item>([\s\S]*?)<\/item>/g;
|
|
131
|
+
let match;
|
|
132
|
+
while ((match = itemRegex.exec(xml)) !== null) {
|
|
133
|
+
const get = (tag) => {
|
|
134
|
+
const m = match[1].match(new RegExp(`<${tag}[^>]*>([\\s\\S]*?)<\\/${tag}>`));
|
|
135
|
+
return m ? m[1].replace(/<!\[CDATA\[|\]\]>/g, "").trim() : "";
|
|
136
|
+
};
|
|
137
|
+
items.push({
|
|
138
|
+
title: get("title"),
|
|
139
|
+
link: get("link"),
|
|
140
|
+
pubDate: get("pubDate"),
|
|
141
|
+
description: get("description").replace(/<[^>]+>/g, "").slice(0, 300),
|
|
142
|
+
source: get("source")
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
return items;
|
|
146
|
+
}
|
|
147
|
+
async function withRetry(fn, retries = 2, delayMs = 1e3) {
|
|
148
|
+
let lastError;
|
|
149
|
+
for (let i = 0; i <= retries; i++) {
|
|
150
|
+
try {
|
|
151
|
+
return await fn();
|
|
152
|
+
} catch (e) {
|
|
153
|
+
lastError = e;
|
|
154
|
+
if (i < retries) await new Promise((r) => setTimeout(r, delayMs * (i + 1)));
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
throw lastError;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export {
|
|
161
|
+
setPostgresFlag,
|
|
162
|
+
autoId,
|
|
163
|
+
getCached,
|
|
164
|
+
setCache,
|
|
165
|
+
checkRateLimit,
|
|
166
|
+
cachedFetchJSON,
|
|
167
|
+
cachedFetchText,
|
|
168
|
+
validateTokenId,
|
|
169
|
+
validateAddress,
|
|
170
|
+
validateSlug,
|
|
171
|
+
clampNumber,
|
|
172
|
+
safeDbExec,
|
|
173
|
+
safeDbQuery,
|
|
174
|
+
safeDbGet,
|
|
175
|
+
parseRSSItems,
|
|
176
|
+
withRetry
|
|
177
|
+
};
|