deso-ag 1.0.0
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/LICENSE +21 -0
- package/README.md +272 -0
- package/dist/fetchers/bluesky.d.ts +3 -0
- package/dist/fetchers/bluesky.d.ts.map +1 -0
- package/dist/fetchers/bluesky.js +154 -0
- package/dist/fetchers/bluesky.js.map +1 -0
- package/dist/fetchers/farcaster.d.ts +3 -0
- package/dist/fetchers/farcaster.d.ts.map +1 -0
- package/dist/fetchers/farcaster.js +149 -0
- package/dist/fetchers/farcaster.js.map +1 -0
- package/dist/fetchers/lens.d.ts +3 -0
- package/dist/fetchers/lens.d.ts.map +1 -0
- package/dist/fetchers/lens.js +125 -0
- package/dist/fetchers/lens.js.map +1 -0
- package/dist/fetchers/nostr.d.ts +3 -0
- package/dist/fetchers/nostr.d.ts.map +1 -0
- package/dist/fetchers/nostr.js +307 -0
- package/dist/fetchers/nostr.js.map +1 -0
- package/dist/formatters/output.d.ts +5 -0
- package/dist/formatters/output.d.ts.map +1 -0
- package/dist/formatters/output.js +225 -0
- package/dist/formatters/output.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +193 -0
- package/dist/index.js.map +1 -0
- package/dist/lib.d.ts +20 -0
- package/dist/lib.d.ts.map +1 -0
- package/dist/lib.js +71 -0
- package/dist/lib.js.map +1 -0
- package/dist/pipeline.d.ts +12 -0
- package/dist/pipeline.d.ts.map +1 -0
- package/dist/pipeline.js +136 -0
- package/dist/pipeline.js.map +1 -0
- package/dist/terms.d.ts +20 -0
- package/dist/terms.d.ts.map +1 -0
- package/dist/terms.js +158 -0
- package/dist/terms.js.map +1 -0
- package/dist/types.d.ts +67 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/search.d.ts +6 -0
- package/dist/utils/search.d.ts.map +1 -0
- package/dist/utils/search.js +13 -0
- package/dist/utils/search.js.map +1 -0
- package/dist/utils/time.d.ts +4 -0
- package/dist/utils/time.d.ts.map +1 -0
- package/dist/utils/time.js +24 -0
- package/dist/utils/time.js.map +1 -0
- package/package.json +62 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { getTimeframeCutoff } from '../utils/time.js';
|
|
2
|
+
import { matchesQuery } from '../utils/search.js';
|
|
3
|
+
// Lens V3 API endpoint
|
|
4
|
+
const LENS_API = 'https://api.lens.xyz/graphql';
|
|
5
|
+
export async function fetchLens(options) {
|
|
6
|
+
const cutoff = getTimeframeCutoff(options.timeframe);
|
|
7
|
+
try {
|
|
8
|
+
const posts = await fetchLensPosts(options.limit || 50, options.query);
|
|
9
|
+
let mappedPosts = posts
|
|
10
|
+
.filter(post => {
|
|
11
|
+
if (!post)
|
|
12
|
+
return false;
|
|
13
|
+
if (new Date(post.timestamp) < cutoff)
|
|
14
|
+
return false;
|
|
15
|
+
// Filter out empty content
|
|
16
|
+
const content = post.metadata?.content || '';
|
|
17
|
+
if (content.trim().length === 0)
|
|
18
|
+
return false;
|
|
19
|
+
return true;
|
|
20
|
+
})
|
|
21
|
+
.map(post => ({
|
|
22
|
+
id: post.slug,
|
|
23
|
+
source: 'lens',
|
|
24
|
+
author: {
|
|
25
|
+
username: post.author?.username?.localName || post.author?.username?.value || 'unknown',
|
|
26
|
+
displayName: post.author?.metadata?.name,
|
|
27
|
+
profileUrl: post.author?.username?.localName
|
|
28
|
+
? `https://hey.xyz/u/${post.author.username.localName}`
|
|
29
|
+
: undefined,
|
|
30
|
+
},
|
|
31
|
+
content: post.metadata?.content || '',
|
|
32
|
+
timestamp: new Date(post.timestamp),
|
|
33
|
+
url: `https://hey.xyz/posts/${post.slug}`,
|
|
34
|
+
engagement: {
|
|
35
|
+
likes: post.stats?.reactions || 0,
|
|
36
|
+
reposts: post.stats?.reposts || 0,
|
|
37
|
+
replies: post.stats?.comments || 0,
|
|
38
|
+
},
|
|
39
|
+
}));
|
|
40
|
+
// Additional client-side query filter (AND semantics for multi-word queries)
|
|
41
|
+
if (options.query) {
|
|
42
|
+
mappedPosts = mappedPosts.filter(p => matchesQuery(p.content, p.tags || [], options.query));
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
posts: mappedPosts,
|
|
46
|
+
source: 'lens',
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
return {
|
|
51
|
+
posts: [],
|
|
52
|
+
source: 'lens',
|
|
53
|
+
error: error instanceof Error ? error.message : 'Unknown error fetching from Lens',
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async function fetchLensPosts(limit, searchQuery) {
|
|
58
|
+
// Build the request object dynamically
|
|
59
|
+
const requestFields = [`pageSize: $pageSize`];
|
|
60
|
+
const variableDefs = [`$pageSize: PageSize!`];
|
|
61
|
+
const variables = {
|
|
62
|
+
pageSize: limitToLensEnum(limit),
|
|
63
|
+
};
|
|
64
|
+
if (searchQuery) {
|
|
65
|
+
requestFields.push(`filter: { searchQuery: $searchQuery }`);
|
|
66
|
+
variableDefs.push(`$searchQuery: String!`);
|
|
67
|
+
variables.searchQuery = searchQuery;
|
|
68
|
+
}
|
|
69
|
+
const graphqlQuery = `
|
|
70
|
+
query GetPosts(${variableDefs.join(', ')}) {
|
|
71
|
+
posts(request: { ${requestFields.join(', ')} }) {
|
|
72
|
+
items {
|
|
73
|
+
... on Post {
|
|
74
|
+
slug
|
|
75
|
+
timestamp
|
|
76
|
+
author {
|
|
77
|
+
username {
|
|
78
|
+
value
|
|
79
|
+
localName
|
|
80
|
+
}
|
|
81
|
+
metadata {
|
|
82
|
+
name
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
metadata {
|
|
86
|
+
... on TextOnlyMetadata { content }
|
|
87
|
+
... on ArticleMetadata { content }
|
|
88
|
+
... on LinkMetadata { content }
|
|
89
|
+
}
|
|
90
|
+
stats {
|
|
91
|
+
reactions
|
|
92
|
+
reposts
|
|
93
|
+
comments
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
`;
|
|
100
|
+
const response = await fetch(LENS_API, {
|
|
101
|
+
method: 'POST',
|
|
102
|
+
headers: {
|
|
103
|
+
'Content-Type': 'application/json',
|
|
104
|
+
'Accept': 'application/json',
|
|
105
|
+
},
|
|
106
|
+
body: JSON.stringify({
|
|
107
|
+
query: graphqlQuery,
|
|
108
|
+
variables,
|
|
109
|
+
}),
|
|
110
|
+
});
|
|
111
|
+
if (!response.ok) {
|
|
112
|
+
throw new Error(`Lens API HTTP error: ${response.status}`);
|
|
113
|
+
}
|
|
114
|
+
const result = await response.json();
|
|
115
|
+
if (result.errors?.length) {
|
|
116
|
+
throw new Error(result.errors[0].message);
|
|
117
|
+
}
|
|
118
|
+
return result.data?.posts?.items || [];
|
|
119
|
+
}
|
|
120
|
+
function limitToLensEnum(limit) {
|
|
121
|
+
if (limit <= 10)
|
|
122
|
+
return 'TEN';
|
|
123
|
+
return 'FIFTY';
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=lens.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lens.js","sourceRoot":"","sources":["../../src/fetchers/lens.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nostr.d.ts","sourceRoot":"","sources":["../../src/fetchers/nostr.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,aAAa,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAuCpE,wBAAsB,UAAU,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC,CAqE7E"}
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
import { getTimeframeCutoff } from '../utils/time.js';
|
|
2
|
+
import { matchesQuery } from '../utils/search.js';
|
|
3
|
+
// Public Nostr relays
|
|
4
|
+
const RELAYS = [
|
|
5
|
+
'wss://relay.damus.io',
|
|
6
|
+
'wss://relay.nostr.band',
|
|
7
|
+
'wss://nos.lol',
|
|
8
|
+
'wss://relay.snort.social',
|
|
9
|
+
];
|
|
10
|
+
// nostr.wine trending API (free, no auth)
|
|
11
|
+
const NOSTR_WINE_API = 'https://api.nostr.wine';
|
|
12
|
+
export async function fetchNostr(options) {
|
|
13
|
+
const cutoff = getTimeframeCutoff(options.timeframe);
|
|
14
|
+
try {
|
|
15
|
+
let events;
|
|
16
|
+
let engagementMap = new Map();
|
|
17
|
+
if (options.query) {
|
|
18
|
+
// For search queries, use relay-based approach
|
|
19
|
+
events = await queryRelays(options, cutoff);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
// For trending, use nostr.wine API + relay fetch for full content
|
|
23
|
+
const trending = await fetchTrendingNotes(options);
|
|
24
|
+
engagementMap = new Map(trending.map(t => [t.event_id, t]));
|
|
25
|
+
const eventIds = trending.map(t => t.event_id);
|
|
26
|
+
events = await fetchEventsByIds(eventIds);
|
|
27
|
+
}
|
|
28
|
+
const profileCache = new Map();
|
|
29
|
+
// Fetch profiles for authors (in parallel, but limit concurrency)
|
|
30
|
+
const uniquePubkeys = [...new Set(events.map(e => e.pubkey))].slice(0, 20);
|
|
31
|
+
await fetchProfiles(uniquePubkeys, profileCache);
|
|
32
|
+
const posts = events
|
|
33
|
+
.filter(event => event.content.trim().length > 0)
|
|
34
|
+
.map(event => {
|
|
35
|
+
const profile = profileCache.get(event.pubkey);
|
|
36
|
+
const npub = pubkeyToNpub(event.pubkey);
|
|
37
|
+
const trending = engagementMap.get(event.id);
|
|
38
|
+
return {
|
|
39
|
+
id: event.id,
|
|
40
|
+
source: 'nostr',
|
|
41
|
+
author: {
|
|
42
|
+
username: profile?.name || npub.slice(0, 12) + '...',
|
|
43
|
+
displayName: profile?.display_name,
|
|
44
|
+
profileUrl: `https://njump.me/${npub}`,
|
|
45
|
+
},
|
|
46
|
+
content: event.content,
|
|
47
|
+
timestamp: new Date(event.created_at * 1000),
|
|
48
|
+
url: `https://njump.me/${event.id}`,
|
|
49
|
+
tags: extractHashtags(event.tags),
|
|
50
|
+
...(trending && {
|
|
51
|
+
engagement: {
|
|
52
|
+
likes: trending.reactions,
|
|
53
|
+
reposts: trending.reposts,
|
|
54
|
+
replies: trending.replies,
|
|
55
|
+
},
|
|
56
|
+
}),
|
|
57
|
+
};
|
|
58
|
+
});
|
|
59
|
+
// Filter by query if provided (AND semantics for multi-word queries)
|
|
60
|
+
const filteredPosts = options.query
|
|
61
|
+
? posts.filter(p => matchesQuery(p.content, p.tags || [], options.query))
|
|
62
|
+
: posts;
|
|
63
|
+
return {
|
|
64
|
+
posts: filteredPosts,
|
|
65
|
+
source: 'nostr',
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
return {
|
|
70
|
+
posts: [],
|
|
71
|
+
source: 'nostr',
|
|
72
|
+
error: error instanceof Error ? error.message : 'Unknown error fetching from Nostr',
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async function fetchTrendingNotes(options) {
|
|
77
|
+
const limit = options.limit || 25;
|
|
78
|
+
const hours = options.timeframe === 'week' ? 48 : options.timeframe === '48h' ? 48 : 24;
|
|
79
|
+
const controller = new AbortController();
|
|
80
|
+
const timeout = setTimeout(() => controller.abort(), 10000);
|
|
81
|
+
try {
|
|
82
|
+
const url = `${NOSTR_WINE_API}/trending?order=reactions&hours=${hours}&limit=${Math.min(limit, 100)}`;
|
|
83
|
+
const response = await fetch(url, {
|
|
84
|
+
signal: controller.signal,
|
|
85
|
+
headers: { 'Accept': 'application/json' },
|
|
86
|
+
});
|
|
87
|
+
clearTimeout(timeout);
|
|
88
|
+
if (!response.ok) {
|
|
89
|
+
throw new Error(`nostr.wine API: ${response.status}`);
|
|
90
|
+
}
|
|
91
|
+
return await response.json();
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
clearTimeout(timeout);
|
|
95
|
+
throw error;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
async function fetchEventsByIds(eventIds) {
|
|
99
|
+
if (eventIds.length === 0)
|
|
100
|
+
return [];
|
|
101
|
+
const events = [];
|
|
102
|
+
const seenIds = new Set();
|
|
103
|
+
// Query multiple relays in parallel for the specific event IDs
|
|
104
|
+
const promises = RELAYS.slice(0, 3).map(relay => queryRelayByIds(relay, eventIds).catch(() => []));
|
|
105
|
+
const results = await Promise.all(promises);
|
|
106
|
+
for (const relayEvents of results) {
|
|
107
|
+
for (const event of relayEvents) {
|
|
108
|
+
if (!seenIds.has(event.id)) {
|
|
109
|
+
seenIds.add(event.id);
|
|
110
|
+
events.push(event);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return events;
|
|
115
|
+
}
|
|
116
|
+
async function queryRelayByIds(relay, ids) {
|
|
117
|
+
return new Promise((resolve) => {
|
|
118
|
+
const events = [];
|
|
119
|
+
let ws = null;
|
|
120
|
+
const timeout = setTimeout(() => {
|
|
121
|
+
if (ws)
|
|
122
|
+
ws.close();
|
|
123
|
+
resolve(events);
|
|
124
|
+
}, 8000);
|
|
125
|
+
try {
|
|
126
|
+
ws = new WebSocket(relay);
|
|
127
|
+
ws.onopen = () => {
|
|
128
|
+
const filter = {
|
|
129
|
+
ids,
|
|
130
|
+
kinds: [1],
|
|
131
|
+
};
|
|
132
|
+
const subId = Math.random().toString(36).slice(2, 10);
|
|
133
|
+
ws?.send(JSON.stringify(['REQ', subId, filter]));
|
|
134
|
+
};
|
|
135
|
+
ws.onmessage = (msg) => {
|
|
136
|
+
try {
|
|
137
|
+
const data = JSON.parse(msg.data);
|
|
138
|
+
if (data[0] === 'EVENT' && data[2]) {
|
|
139
|
+
events.push(data[2]);
|
|
140
|
+
}
|
|
141
|
+
else if (data[0] === 'EOSE') {
|
|
142
|
+
clearTimeout(timeout);
|
|
143
|
+
ws?.close();
|
|
144
|
+
resolve(events);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
// Ignore parse errors
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
ws.onerror = () => {
|
|
152
|
+
clearTimeout(timeout);
|
|
153
|
+
resolve(events);
|
|
154
|
+
};
|
|
155
|
+
ws.onclose = () => {
|
|
156
|
+
clearTimeout(timeout);
|
|
157
|
+
resolve(events);
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
clearTimeout(timeout);
|
|
162
|
+
resolve(events);
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
async function queryRelays(options, cutoff) {
|
|
167
|
+
const since = Math.floor(cutoff.getTime() / 1000);
|
|
168
|
+
const limit = options.limit || 50;
|
|
169
|
+
const events = [];
|
|
170
|
+
const seenIds = new Set();
|
|
171
|
+
// Query multiple relays in parallel
|
|
172
|
+
const promises = RELAYS.slice(0, 3).map(relay => queryRelay(relay, since, limit, options.query)
|
|
173
|
+
.catch(() => []));
|
|
174
|
+
const results = await Promise.all(promises);
|
|
175
|
+
for (const relayEvents of results) {
|
|
176
|
+
for (const event of relayEvents) {
|
|
177
|
+
if (!seenIds.has(event.id)) {
|
|
178
|
+
seenIds.add(event.id);
|
|
179
|
+
events.push(event);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
// Sort by timestamp descending
|
|
184
|
+
events.sort((a, b) => b.created_at - a.created_at);
|
|
185
|
+
return events.slice(0, limit);
|
|
186
|
+
}
|
|
187
|
+
async function queryRelay(relay, since, limit, query) {
|
|
188
|
+
return new Promise((resolve) => {
|
|
189
|
+
const events = [];
|
|
190
|
+
let ws = null;
|
|
191
|
+
const timeout = setTimeout(() => {
|
|
192
|
+
if (ws)
|
|
193
|
+
ws.close();
|
|
194
|
+
resolve(events);
|
|
195
|
+
}, 5000);
|
|
196
|
+
try {
|
|
197
|
+
// Use global WebSocket (polyfilled by websocket-polyfill in Node)
|
|
198
|
+
ws = new WebSocket(relay);
|
|
199
|
+
ws.onopen = () => {
|
|
200
|
+
const filter = {
|
|
201
|
+
kinds: [1], // Text notes only
|
|
202
|
+
since,
|
|
203
|
+
limit: Math.min(limit, 100),
|
|
204
|
+
};
|
|
205
|
+
// If query contains #hashtag, search by tag
|
|
206
|
+
if (query?.startsWith('#')) {
|
|
207
|
+
filter['#t'] = [query.slice(1).toLowerCase()];
|
|
208
|
+
}
|
|
209
|
+
const subId = Math.random().toString(36).slice(2, 10);
|
|
210
|
+
ws?.send(JSON.stringify(['REQ', subId, filter]));
|
|
211
|
+
};
|
|
212
|
+
ws.onmessage = (msg) => {
|
|
213
|
+
try {
|
|
214
|
+
const data = JSON.parse(msg.data);
|
|
215
|
+
if (data[0] === 'EVENT' && data[2]) {
|
|
216
|
+
events.push(data[2]);
|
|
217
|
+
}
|
|
218
|
+
else if (data[0] === 'EOSE') {
|
|
219
|
+
clearTimeout(timeout);
|
|
220
|
+
ws?.close();
|
|
221
|
+
resolve(events);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
// Ignore parse errors
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
ws.onerror = () => {
|
|
229
|
+
clearTimeout(timeout);
|
|
230
|
+
resolve(events);
|
|
231
|
+
};
|
|
232
|
+
ws.onclose = () => {
|
|
233
|
+
clearTimeout(timeout);
|
|
234
|
+
resolve(events);
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
catch {
|
|
238
|
+
clearTimeout(timeout);
|
|
239
|
+
resolve(events);
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
async function fetchProfiles(pubkeys, cache) {
|
|
244
|
+
if (pubkeys.length === 0)
|
|
245
|
+
return;
|
|
246
|
+
const relay = RELAYS[0];
|
|
247
|
+
return new Promise((resolve) => {
|
|
248
|
+
let ws = null;
|
|
249
|
+
const timeout = setTimeout(() => {
|
|
250
|
+
if (ws)
|
|
251
|
+
ws.close();
|
|
252
|
+
resolve();
|
|
253
|
+
}, 3000);
|
|
254
|
+
try {
|
|
255
|
+
ws = new WebSocket(relay);
|
|
256
|
+
ws.onopen = () => {
|
|
257
|
+
const filter = {
|
|
258
|
+
kinds: [0], // Metadata
|
|
259
|
+
authors: pubkeys,
|
|
260
|
+
};
|
|
261
|
+
const subId = 'profiles-' + Math.random().toString(36).slice(2, 6);
|
|
262
|
+
ws?.send(JSON.stringify(['REQ', subId, filter]));
|
|
263
|
+
};
|
|
264
|
+
ws.onmessage = (msg) => {
|
|
265
|
+
try {
|
|
266
|
+
const data = JSON.parse(msg.data);
|
|
267
|
+
if (data[0] === 'EVENT' && data[2]) {
|
|
268
|
+
const event = data[2];
|
|
269
|
+
const profile = JSON.parse(event.content);
|
|
270
|
+
cache.set(event.pubkey, profile);
|
|
271
|
+
}
|
|
272
|
+
else if (data[0] === 'EOSE') {
|
|
273
|
+
clearTimeout(timeout);
|
|
274
|
+
ws?.close();
|
|
275
|
+
resolve();
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
catch {
|
|
279
|
+
// Ignore parse errors
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
ws.onerror = () => {
|
|
283
|
+
clearTimeout(timeout);
|
|
284
|
+
resolve();
|
|
285
|
+
};
|
|
286
|
+
ws.onclose = () => {
|
|
287
|
+
clearTimeout(timeout);
|
|
288
|
+
resolve();
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
catch {
|
|
292
|
+
clearTimeout(timeout);
|
|
293
|
+
resolve();
|
|
294
|
+
}
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
function extractHashtags(tags) {
|
|
298
|
+
return tags
|
|
299
|
+
.filter(tag => tag[0] === 't')
|
|
300
|
+
.map(tag => tag[1]);
|
|
301
|
+
}
|
|
302
|
+
function pubkeyToNpub(pubkey) {
|
|
303
|
+
// Simplified npub encoding (returns hex for now, full bech32 requires more deps)
|
|
304
|
+
// In production, use nostr-tools nip19.npubEncode
|
|
305
|
+
return `npub1${pubkey.slice(0, 20)}`;
|
|
306
|
+
}
|
|
307
|
+
//# sourceMappingURL=nostr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nostr.js","sourceRoot":"","sources":["../../src/fetchers/nostr.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,sBAAsB;AACtB,MAAM,MAAM,GAAG;IACb,sBAAsB;IACtB,wBAAwB;IACxB,eAAe;IACf,0BAA0B;CAC3B,CAAC;AAEF,0CAA0C;AAC1C,MAAM,cAAc,GAAG,wBAAwB,CAAC;AA0BhD,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAAsB;IACrD,MAAM,MAAM,GAAG,kBAAkB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAErD,IAAI,CAAC;QACH,IAAI,MAAoB,CAAC;QACzB,IAAI,aAAa,GAAG,IAAI,GAAG,EAAwB,CAAC;QAEpD,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YAClB,+CAA+C;YAC/C,MAAM,GAAG,MAAM,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC9C,CAAC;aAAM,CAAC;YACN,kEAAkE;YAClE,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,OAAO,CAAC,CAAC;YACnD,aAAa,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5D,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;YAC/C,MAAM,GAAG,MAAM,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QAC5C,CAAC;QAED,MAAM,YAAY,GAAG,IAAI,GAAG,EAAwB,CAAC;QAErD,kEAAkE;QAClE,MAAM,aAAa,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC3E,MAAM,aAAa,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;QAEjD,MAAM,KAAK,GAAW,MAAM;aACzB,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;aAChD,GAAG,CAAC,KAAK,CAAC,EAAE;YACX,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAC/C,MAAM,IAAI,GAAG,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACxC,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAE7C,OAAO;gBACL,EAAE,EAAE,KAAK,CAAC,EAAE;gBACZ,MAAM,EAAE,OAAgB;gBACxB,MAAM,EAAE;oBACN,QAAQ,EAAE,OAAO,EAAE,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK;oBACpD,WAAW,EAAE,OAAO,EAAE,YAAY;oBAClC,UAAU,EAAE,oBAAoB,IAAI,EAAE;iBACvC;gBACD,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,SAAS,EAAE,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC;gBAC5C,GAAG,EAAE,oBAAoB,KAAK,CAAC,EAAE,EAAE;gBACnC,IAAI,EAAE,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC;gBACjC,GAAG,CAAC,QAAQ,IAAI;oBACd,UAAU,EAAE;wBACV,KAAK,EAAE,QAAQ,CAAC,SAAS;wBACzB,OAAO,EAAE,QAAQ,CAAC,OAAO;wBACzB,OAAO,EAAE,QAAQ,CAAC,OAAO;qBAC1B;iBACF,CAAC;aACH,CAAC;QACJ,CAAC,CAAC,CAAC;QAEL,qEAAqE;QACrE,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK;YACjC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,IAAI,EAAE,EAAE,OAAO,CAAC,KAAM,CAAC,CAAC;YAC1E,CAAC,CAAC,KAAK,CAAC;QAEV,OAAO;YACL,KAAK,EAAE,aAAa;YACpB,MAAM,EAAE,OAAO;SAChB,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,KAAK,EAAE,EAAE;YACT,MAAM,EAAE,OAAO;YACf,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,mCAAmC;SACpF,CAAC;IACJ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,kBAAkB,CAAC,OAAsB;IACtD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;IAClC,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAExF,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,KAAK,CAAC,CAAC;IAE5D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,GAAG,cAAc,mCAAmC,KAAK,UAAU,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC;QACtG,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,OAAO,EAAE,EAAE,QAAQ,EAAE,kBAAkB,EAAE;SAC1C,CAAC,CAAC;QAEH,YAAY,CAAC,OAAO,CAAC,CAAC;QAEtB,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QACxD,CAAC;QAED,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAoB,CAAC;IACjD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,YAAY,CAAC,OAAO,CAAC,CAAC;QACtB,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,QAAkB;IAChD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAErC,MAAM,MAAM,GAAiB,EAAE,CAAC;IAChC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAElC,+DAA+D;IAC/D,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAC9C,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAkB,CAAC,CACjE,CAAC;IAEF,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAE5C,KAAK,MAAM,WAAW,IAAI,OAAO,EAAE,CAAC;QAClC,KAAK,MAAM,KAAK,IAAI,WAAW,EAAE,CAAC;YAChC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;gBAC3B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBACtB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,KAAa,EAAE,GAAa;IACzD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,MAAM,GAAiB,EAAE,CAAC;QAChC,IAAI,EAAE,GAAqB,IAAI,CAAC;QAEhC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;YAC9B,IAAI,EAAE;gBAAE,EAAE,CAAC,KAAK,EAAE,CAAC;YACnB,OAAO,CAAC,MAAM,CAAC,CAAC;QAClB,CAAC,EAAE,IAAI,CAAC,CAAC;QAET,IAAI,CAAC;YACH,EAAE,GAAG,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC;YAE1B,EAAE,CAAC,MAAM,GAAG,GAAG,EAAE;gBACf,MAAM,MAAM,GAAG;oBACb,GAAG;oBACH,KAAK,EAAE,CAAC,CAAC,CAAC;iBACX,CAAC;gBACF,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACtD,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;YACnD,CAAC,CAAC;YAEF,EAAE,CAAC,SAAS,GAAG,CAAC,GAAG,EAAE,EAAE;gBACrB,IAAI,CAAC;oBACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAc,CAAC,CAAC;oBAC5C,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;wBACnC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAe,CAAC,CAAC;oBACrC,CAAC;yBAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC;wBAC9B,YAAY,CAAC,OAAO,CAAC,CAAC;wBACtB,EAAE,EAAE,KAAK,EAAE,CAAC;wBACZ,OAAO,CAAC,MAAM,CAAC,CAAC;oBAClB,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,sBAAsB;gBACxB,CAAC;YACH,CAAC,CAAC;YAEF,EAAE,CAAC,OAAO,GAAG,GAAG,EAAE;gBAChB,YAAY,CAAC,OAAO,CAAC,CAAC;gBACtB,OAAO,CAAC,MAAM,CAAC,CAAC;YAClB,CAAC,CAAC;YAEF,EAAE,CAAC,OAAO,GAAG,GAAG,EAAE;gBAChB,YAAY,CAAC,OAAO,CAAC,CAAC;gBACtB,OAAO,CAAC,MAAM,CAAC,CAAC;YAClB,CAAC,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,YAAY,CAAC,OAAO,CAAC,CAAC;YACtB,OAAO,CAAC,MAAM,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,OAAsB,EAAE,MAAY;IAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IAClD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;IAClC,MAAM,MAAM,GAAiB,EAAE,CAAC;IAChC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAElC,oCAAoC;IACpC,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAC9C,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC;SAC3C,KAAK,CAAC,GAAG,EAAE,CAAC,EAAkB,CAAC,CACnC,CAAC;IAEF,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAE5C,KAAK,MAAM,WAAW,IAAI,OAAO,EAAE,CAAC;QAClC,KAAK,MAAM,KAAK,IAAI,WAAW,EAAE,CAAC;YAChC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;gBAC3B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBACtB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC;QACH,CAAC;IACH,CAAC;IAED,+BAA+B;IAC/B,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC;IACnD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;AAChC,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,KAAa,EAAE,KAAa,EAAE,KAAa,EAAE,KAAc;IACnF,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,MAAM,GAAiB,EAAE,CAAC;QAChC,IAAI,EAAE,GAAqB,IAAI,CAAC;QAEhC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;YAC9B,IAAI,EAAE;gBAAE,EAAE,CAAC,KAAK,EAAE,CAAC;YACnB,OAAO,CAAC,MAAM,CAAC,CAAC;QAClB,CAAC,EAAE,IAAI,CAAC,CAAC;QAET,IAAI,CAAC;YACH,kEAAkE;YAClE,EAAE,GAAG,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC;YAE1B,EAAE,CAAC,MAAM,GAAG,GAAG,EAAE;gBACf,MAAM,MAAM,GAA4B;oBACtC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,kBAAkB;oBAC9B,KAAK;oBACL,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC;iBAC5B,CAAC;gBAEF,4CAA4C;gBAC5C,IAAI,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC3B,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;gBAChD,CAAC;gBAED,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACtD,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;YACnD,CAAC,CAAC;YAEF,EAAE,CAAC,SAAS,GAAG,CAAC,GAAG,EAAE,EAAE;gBACrB,IAAI,CAAC;oBACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAc,CAAC,CAAC;oBAC5C,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;wBACnC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAe,CAAC,CAAC;oBACrC,CAAC;yBAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC;wBAC9B,YAAY,CAAC,OAAO,CAAC,CAAC;wBACtB,EAAE,EAAE,KAAK,EAAE,CAAC;wBACZ,OAAO,CAAC,MAAM,CAAC,CAAC;oBAClB,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,sBAAsB;gBACxB,CAAC;YACH,CAAC,CAAC;YAEF,EAAE,CAAC,OAAO,GAAG,GAAG,EAAE;gBAChB,YAAY,CAAC,OAAO,CAAC,CAAC;gBACtB,OAAO,CAAC,MAAM,CAAC,CAAC;YAClB,CAAC,CAAC;YAEF,EAAE,CAAC,OAAO,GAAG,GAAG,EAAE;gBAChB,YAAY,CAAC,OAAO,CAAC,CAAC;gBACtB,OAAO,CAAC,MAAM,CAAC,CAAC;YAClB,CAAC,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,YAAY,CAAC,OAAO,CAAC,CAAC;YACtB,OAAO,CAAC,MAAM,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,OAAiB,EAAE,KAAgC;IAC9E,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAEjC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IAExB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,IAAI,EAAE,GAAqB,IAAI,CAAC;QAChC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;YAC9B,IAAI,EAAE;gBAAE,EAAE,CAAC,KAAK,EAAE,CAAC;YACnB,OAAO,EAAE,CAAC;QACZ,CAAC,EAAE,IAAI,CAAC,CAAC;QAET,IAAI,CAAC;YACH,EAAE,GAAG,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC;YAE1B,EAAE,CAAC,MAAM,GAAG,GAAG,EAAE;gBACf,MAAM,MAAM,GAAG;oBACb,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW;oBACvB,OAAO,EAAE,OAAO;iBACjB,CAAC;gBACF,MAAM,KAAK,GAAG,WAAW,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBACnE,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;YACnD,CAAC,CAAC;YAEF,EAAE,CAAC,SAAS,GAAG,CAAC,GAAG,EAAE,EAAE;gBACrB,IAAI,CAAC;oBACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAc,CAAC,CAAC;oBAC5C,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;wBACnC,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAe,CAAC;wBACpC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAiB,CAAC;wBAC1D,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;oBACnC,CAAC;yBAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC;wBAC9B,YAAY,CAAC,OAAO,CAAC,CAAC;wBACtB,EAAE,EAAE,KAAK,EAAE,CAAC;wBACZ,OAAO,EAAE,CAAC;oBACZ,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,sBAAsB;gBACxB,CAAC;YACH,CAAC,CAAC;YAEF,EAAE,CAAC,OAAO,GAAG,GAAG,EAAE;gBAChB,YAAY,CAAC,OAAO,CAAC,CAAC;gBACtB,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC;YAEF,EAAE,CAAC,OAAO,GAAG,GAAG,EAAE;gBAChB,YAAY,CAAC,OAAO,CAAC,CAAC;gBACtB,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,YAAY,CAAC,OAAO,CAAC,CAAC;YACtB,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,eAAe,CAAC,IAAgB;IACvC,OAAO,IAAI;SACR,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC;SAC7B,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AACxB,CAAC;AAED,SAAS,YAAY,CAAC,MAAc;IAClC,iFAAiF;IACjF,kDAAkD;IAClD,OAAO,QAAQ,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Post, OutputFormat, AggregateResult, TermsResult } from '../types.js';
|
|
2
|
+
export declare function computeEngagementScore(post: Post): number;
|
|
3
|
+
export declare function formatOutput(posts: Post[], format: OutputFormat, meta?: AggregateResult['meta'], termsResult?: TermsResult): string;
|
|
4
|
+
export declare function formatTermsSummary(result: TermsResult): string;
|
|
5
|
+
//# sourceMappingURL=output.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/formatters/output.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,YAAY,EAAU,eAAe,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG5F,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAIzD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,CAAC,EAAE,eAAe,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,EAAE,WAAW,GAAG,MAAM,CAgBnI;AA+LD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAoC9D"}
|