webring 0.0.0-dev.706

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.
@@ -0,0 +1,467 @@
1
+ import { z } from "zod/v3";
2
+ export type Source = z.infer<typeof SourceSchema>;
3
+ /** An RSS source */
4
+ declare const SourceSchema: z.ZodObject<{
5
+ /** The URL of an RSS feed */
6
+ url: z.ZodString;
7
+ /** A title to describe the feed */
8
+ title: z.ZodString;
9
+ /** Takes a entry preview and returns whether or not it should be displayed */
10
+ filter: z.ZodOptional<z.ZodFunction<z.ZodTuple<[z.ZodString], z.ZodUnknown>, z.ZodBoolean>>;
11
+ }, "strip", z.ZodTypeAny, {
12
+ url: string;
13
+ title: string;
14
+ filter?: ((args_0: string, ...args: unknown[]) => boolean) | undefined;
15
+ }, {
16
+ url: string;
17
+ title: string;
18
+ filter?: ((args_0: string, ...args: unknown[]) => boolean) | undefined;
19
+ }>;
20
+ export type CacheConfiguration = z.infer<typeof CacheConfigurationSchema>;
21
+ /** Configuration for the cache */
22
+ declare const CacheConfigurationSchema: z.ZodObject<{
23
+ /** How long to cache a result for */
24
+ cache_duration_minutes: z.ZodDefault<z.ZodNumber>;
25
+ /** The location of a file to use as a cache */
26
+ cache_file: z.ZodDefault<z.ZodString>;
27
+ }, "strip", z.ZodTypeAny, {
28
+ cache_duration_minutes: number;
29
+ cache_file: string;
30
+ }, {
31
+ cache_duration_minutes?: number | undefined;
32
+ cache_file?: string | undefined;
33
+ }>;
34
+ export type Configuration = z.infer<typeof ConfigurationSchema>;
35
+ /** A configuration object with caching possibly configured */
36
+ declare const ConfigurationSchema: z.ZodObject<{
37
+ /** A list of sources to fetch */
38
+ sources: z.ZodArray<z.ZodObject<{
39
+ /** The URL of an RSS feed */
40
+ url: z.ZodString;
41
+ /** A title to describe the feed */
42
+ title: z.ZodString;
43
+ /** Takes a entry preview and returns whether or not it should be displayed */
44
+ filter: z.ZodOptional<z.ZodFunction<z.ZodTuple<[z.ZodString], z.ZodUnknown>, z.ZodBoolean>>;
45
+ }, "strip", z.ZodTypeAny, {
46
+ url: string;
47
+ title: string;
48
+ filter?: ((args_0: string, ...args: unknown[]) => boolean) | undefined;
49
+ }, {
50
+ url: string;
51
+ title: string;
52
+ filter?: ((args_0: string, ...args: unknown[]) => boolean) | undefined;
53
+ }>, "many">;
54
+ /** Return the n latest updates from the source list. */
55
+ number: z.ZodDefault<z.ZodNumber>;
56
+ /** How many words the preview field should be truncated to in characters after HTML has been sanitized and parsed. */
57
+ truncate: z.ZodDefault<z.ZodNumber>;
58
+ /** Configuration for the cache */
59
+ cache: z.ZodOptional<z.ZodObject<{
60
+ /** How long to cache a result for */
61
+ cache_duration_minutes: z.ZodDefault<z.ZodNumber>;
62
+ /** The location of a file to use as a cache */
63
+ cache_file: z.ZodDefault<z.ZodString>;
64
+ }, "strip", z.ZodTypeAny, {
65
+ cache_duration_minutes: number;
66
+ cache_file: string;
67
+ }, {
68
+ cache_duration_minutes?: number | undefined;
69
+ cache_file?: string | undefined;
70
+ }>>;
71
+ /** Randomize the output order */
72
+ shuffle: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
73
+ }, "strip", z.ZodTypeAny, {
74
+ number: number;
75
+ sources: {
76
+ url: string;
77
+ title: string;
78
+ filter?: ((args_0: string, ...args: unknown[]) => boolean) | undefined;
79
+ }[];
80
+ truncate: number;
81
+ cache?: {
82
+ cache_duration_minutes: number;
83
+ cache_file: string;
84
+ } | undefined;
85
+ shuffle?: boolean | undefined;
86
+ }, {
87
+ sources: {
88
+ url: string;
89
+ title: string;
90
+ filter?: ((args_0: string, ...args: unknown[]) => boolean) | undefined;
91
+ }[];
92
+ number?: number | undefined;
93
+ truncate?: number | undefined;
94
+ cache?: {
95
+ cache_duration_minutes?: number | undefined;
96
+ cache_file?: string | undefined;
97
+ } | undefined;
98
+ shuffle?: boolean | undefined;
99
+ }>;
100
+ export type CachedConfiguration = z.infer<typeof CachedConfigurationSchema>;
101
+ /** A configuration object with caching definitely configured */
102
+ export declare const CachedConfigurationSchema: z.ZodObject<{
103
+ sources: z.ZodArray<z.ZodObject<{
104
+ /** The URL of an RSS feed */
105
+ url: z.ZodString;
106
+ /** A title to describe the feed */
107
+ title: z.ZodString;
108
+ /** Takes a entry preview and returns whether or not it should be displayed */
109
+ filter: z.ZodOptional<z.ZodFunction<z.ZodTuple<[z.ZodString], z.ZodUnknown>, z.ZodBoolean>>;
110
+ }, "strip", z.ZodTypeAny, {
111
+ url: string;
112
+ title: string;
113
+ filter?: ((args_0: string, ...args: unknown[]) => boolean) | undefined;
114
+ }, {
115
+ url: string;
116
+ title: string;
117
+ filter?: ((args_0: string, ...args: unknown[]) => boolean) | undefined;
118
+ }>, "many">;
119
+ number: z.ZodDefault<z.ZodNumber>;
120
+ truncate: z.ZodDefault<z.ZodNumber>;
121
+ shuffle: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
122
+ } & {
123
+ cache: z.ZodObject<{
124
+ /** How long to cache a result for */
125
+ cache_duration_minutes: z.ZodDefault<z.ZodNumber>;
126
+ /** The location of a file to use as a cache */
127
+ cache_file: z.ZodDefault<z.ZodString>;
128
+ }, "strip", z.ZodTypeAny, {
129
+ cache_duration_minutes: number;
130
+ cache_file: string;
131
+ }, {
132
+ cache_duration_minutes?: number | undefined;
133
+ cache_file?: string | undefined;
134
+ }>;
135
+ }, "strip", z.ZodTypeAny, {
136
+ number: number;
137
+ sources: {
138
+ url: string;
139
+ title: string;
140
+ filter?: ((args_0: string, ...args: unknown[]) => boolean) | undefined;
141
+ }[];
142
+ truncate: number;
143
+ cache: {
144
+ cache_duration_minutes: number;
145
+ cache_file: string;
146
+ };
147
+ shuffle?: boolean | undefined;
148
+ }, {
149
+ sources: {
150
+ url: string;
151
+ title: string;
152
+ filter?: ((args_0: string, ...args: unknown[]) => boolean) | undefined;
153
+ }[];
154
+ cache: {
155
+ cache_duration_minutes?: number | undefined;
156
+ cache_file?: string | undefined;
157
+ };
158
+ number?: number | undefined;
159
+ truncate?: number | undefined;
160
+ shuffle?: boolean | undefined;
161
+ }>;
162
+ export type ResultEntry = z.infer<typeof ResultEntrySchema>;
163
+ /** A single entry from an RSS feed */
164
+ declare const ResultEntrySchema: z.ZodObject<{
165
+ /** The title of the entry */
166
+ title: z.ZodString;
167
+ /** A direct link to the entry */
168
+ url: z.ZodString;
169
+ /** The date of the entry */
170
+ date: z.ZodDate;
171
+ /** The source the entry is from */
172
+ source: z.ZodObject<{
173
+ /** The URL of an RSS feed */
174
+ url: z.ZodString;
175
+ /** A title to describe the feed */
176
+ title: z.ZodString;
177
+ /** Takes a entry preview and returns whether or not it should be displayed */
178
+ filter: z.ZodOptional<z.ZodFunction<z.ZodTuple<[z.ZodString], z.ZodUnknown>, z.ZodBoolean>>;
179
+ }, "strip", z.ZodTypeAny, {
180
+ url: string;
181
+ title: string;
182
+ filter?: ((args_0: string, ...args: unknown[]) => boolean) | undefined;
183
+ }, {
184
+ url: string;
185
+ title: string;
186
+ filter?: ((args_0: string, ...args: unknown[]) => boolean) | undefined;
187
+ }>;
188
+ /** A preview of the entry. This may contain sanitized HTML. */
189
+ preview: z.ZodOptional<z.ZodString>;
190
+ }, "strip", z.ZodTypeAny, {
191
+ url: string;
192
+ title: string;
193
+ date: Date;
194
+ source: {
195
+ url: string;
196
+ title: string;
197
+ filter?: ((args_0: string, ...args: unknown[]) => boolean) | undefined;
198
+ };
199
+ preview?: string | undefined;
200
+ }, {
201
+ url: string;
202
+ title: string;
203
+ date: Date;
204
+ source: {
205
+ url: string;
206
+ title: string;
207
+ filter?: ((args_0: string, ...args: unknown[]) => boolean) | undefined;
208
+ };
209
+ preview?: string | undefined;
210
+ }>;
211
+ export type Result = z.infer<typeof ResultSchema>;
212
+ /** A list of results */
213
+ export declare const ResultSchema: z.ZodArray<z.ZodObject<{
214
+ /** The title of the entry */
215
+ title: z.ZodString;
216
+ /** A direct link to the entry */
217
+ url: z.ZodString;
218
+ /** The date of the entry */
219
+ date: z.ZodDate;
220
+ /** The source the entry is from */
221
+ source: z.ZodObject<{
222
+ /** The URL of an RSS feed */
223
+ url: z.ZodString;
224
+ /** A title to describe the feed */
225
+ title: z.ZodString;
226
+ /** Takes a entry preview and returns whether or not it should be displayed */
227
+ filter: z.ZodOptional<z.ZodFunction<z.ZodTuple<[z.ZodString], z.ZodUnknown>, z.ZodBoolean>>;
228
+ }, "strip", z.ZodTypeAny, {
229
+ url: string;
230
+ title: string;
231
+ filter?: ((args_0: string, ...args: unknown[]) => boolean) | undefined;
232
+ }, {
233
+ url: string;
234
+ title: string;
235
+ filter?: ((args_0: string, ...args: unknown[]) => boolean) | undefined;
236
+ }>;
237
+ /** A preview of the entry. This may contain sanitized HTML. */
238
+ preview: z.ZodOptional<z.ZodString>;
239
+ }, "strip", z.ZodTypeAny, {
240
+ url: string;
241
+ title: string;
242
+ date: Date;
243
+ source: {
244
+ url: string;
245
+ title: string;
246
+ filter?: ((args_0: string, ...args: unknown[]) => boolean) | undefined;
247
+ };
248
+ preview?: string | undefined;
249
+ }, {
250
+ url: string;
251
+ title: string;
252
+ date: Date;
253
+ source: {
254
+ url: string;
255
+ title: string;
256
+ filter?: ((args_0: string, ...args: unknown[]) => boolean) | undefined;
257
+ };
258
+ preview?: string | undefined;
259
+ }>, "many">;
260
+ export type CacheEntry = z.infer<typeof CacheEntrySchema>;
261
+ /** A single cache entry */
262
+ export declare const CacheEntrySchema: z.ZodObject<{
263
+ /** The time a source was last checked */
264
+ timestamp: z.ZodDate;
265
+ /** The data from the source */
266
+ data: z.ZodObject<{
267
+ /** The title of the entry */
268
+ title: z.ZodString;
269
+ /** A direct link to the entry */
270
+ url: z.ZodString;
271
+ /** The date of the entry */
272
+ date: z.ZodDate;
273
+ /** The source the entry is from */
274
+ source: z.ZodObject<{
275
+ /** The URL of an RSS feed */
276
+ url: z.ZodString;
277
+ /** A title to describe the feed */
278
+ title: z.ZodString;
279
+ /** Takes a entry preview and returns whether or not it should be displayed */
280
+ filter: z.ZodOptional<z.ZodFunction<z.ZodTuple<[z.ZodString], z.ZodUnknown>, z.ZodBoolean>>;
281
+ }, "strip", z.ZodTypeAny, {
282
+ url: string;
283
+ title: string;
284
+ filter?: ((args_0: string, ...args: unknown[]) => boolean) | undefined;
285
+ }, {
286
+ url: string;
287
+ title: string;
288
+ filter?: ((args_0: string, ...args: unknown[]) => boolean) | undefined;
289
+ }>;
290
+ /** A preview of the entry. This may contain sanitized HTML. */
291
+ preview: z.ZodOptional<z.ZodString>;
292
+ }, "strip", z.ZodTypeAny, {
293
+ url: string;
294
+ title: string;
295
+ date: Date;
296
+ source: {
297
+ url: string;
298
+ title: string;
299
+ filter?: ((args_0: string, ...args: unknown[]) => boolean) | undefined;
300
+ };
301
+ preview?: string | undefined;
302
+ }, {
303
+ url: string;
304
+ title: string;
305
+ date: Date;
306
+ source: {
307
+ url: string;
308
+ title: string;
309
+ filter?: ((args_0: string, ...args: unknown[]) => boolean) | undefined;
310
+ };
311
+ preview?: string | undefined;
312
+ }>;
313
+ }, "strip", z.ZodTypeAny, {
314
+ timestamp: Date;
315
+ data: {
316
+ url: string;
317
+ title: string;
318
+ date: Date;
319
+ source: {
320
+ url: string;
321
+ title: string;
322
+ filter?: ((args_0: string, ...args: unknown[]) => boolean) | undefined;
323
+ };
324
+ preview?: string | undefined;
325
+ };
326
+ }, {
327
+ timestamp: Date;
328
+ data: {
329
+ url: string;
330
+ title: string;
331
+ date: Date;
332
+ source: {
333
+ url: string;
334
+ title: string;
335
+ filter?: ((args_0: string, ...args: unknown[]) => boolean) | undefined;
336
+ };
337
+ preview?: string | undefined;
338
+ };
339
+ }>;
340
+ export type Cache = z.infer<typeof CacheSchema>;
341
+ /** A mapping of source URLs to cache entries */
342
+ export declare const CacheSchema: z.ZodRecord<z.ZodString, z.ZodObject<{
343
+ /** The time a source was last checked */
344
+ timestamp: z.ZodDate;
345
+ /** The data from the source */
346
+ data: z.ZodObject<{
347
+ /** The title of the entry */
348
+ title: z.ZodString;
349
+ /** A direct link to the entry */
350
+ url: z.ZodString;
351
+ /** The date of the entry */
352
+ date: z.ZodDate;
353
+ /** The source the entry is from */
354
+ source: z.ZodObject<{
355
+ /** The URL of an RSS feed */
356
+ url: z.ZodString;
357
+ /** A title to describe the feed */
358
+ title: z.ZodString;
359
+ /** Takes a entry preview and returns whether or not it should be displayed */
360
+ filter: z.ZodOptional<z.ZodFunction<z.ZodTuple<[z.ZodString], z.ZodUnknown>, z.ZodBoolean>>;
361
+ }, "strip", z.ZodTypeAny, {
362
+ url: string;
363
+ title: string;
364
+ filter?: ((args_0: string, ...args: unknown[]) => boolean) | undefined;
365
+ }, {
366
+ url: string;
367
+ title: string;
368
+ filter?: ((args_0: string, ...args: unknown[]) => boolean) | undefined;
369
+ }>;
370
+ /** A preview of the entry. This may contain sanitized HTML. */
371
+ preview: z.ZodOptional<z.ZodString>;
372
+ }, "strip", z.ZodTypeAny, {
373
+ url: string;
374
+ title: string;
375
+ date: Date;
376
+ source: {
377
+ url: string;
378
+ title: string;
379
+ filter?: ((args_0: string, ...args: unknown[]) => boolean) | undefined;
380
+ };
381
+ preview?: string | undefined;
382
+ }, {
383
+ url: string;
384
+ title: string;
385
+ date: Date;
386
+ source: {
387
+ url: string;
388
+ title: string;
389
+ filter?: ((args_0: string, ...args: unknown[]) => boolean) | undefined;
390
+ };
391
+ preview?: string | undefined;
392
+ }>;
393
+ }, "strip", z.ZodTypeAny, {
394
+ timestamp: Date;
395
+ data: {
396
+ url: string;
397
+ title: string;
398
+ date: Date;
399
+ source: {
400
+ url: string;
401
+ title: string;
402
+ filter?: ((args_0: string, ...args: unknown[]) => boolean) | undefined;
403
+ };
404
+ preview?: string | undefined;
405
+ };
406
+ }, {
407
+ timestamp: Date;
408
+ data: {
409
+ url: string;
410
+ title: string;
411
+ date: Date;
412
+ source: {
413
+ url: string;
414
+ title: string;
415
+ filter?: ((args_0: string, ...args: unknown[]) => boolean) | undefined;
416
+ };
417
+ preview?: string | undefined;
418
+ };
419
+ }>>;
420
+ /** The expected format fetched RSS feed entries */
421
+ export declare const FeedEntrySchema: z.ZodEffects<z.ZodObject<{
422
+ title: z.ZodString;
423
+ link: z.ZodString;
424
+ isoDate: z.ZodOptional<z.ZodDate>;
425
+ pubDate: z.ZodOptional<z.ZodDate>;
426
+ content: z.ZodOptional<z.ZodString>;
427
+ contentSnippet: z.ZodOptional<z.ZodString>;
428
+ "content:encoded": z.ZodOptional<z.ZodString>;
429
+ description: z.ZodOptional<z.ZodString>;
430
+ }, "strip", z.ZodTypeAny, {
431
+ title: string;
432
+ link: string;
433
+ isoDate?: Date | undefined;
434
+ pubDate?: Date | undefined;
435
+ content?: string | undefined;
436
+ contentSnippet?: string | undefined;
437
+ "content:encoded"?: string | undefined;
438
+ description?: string | undefined;
439
+ }, {
440
+ title: string;
441
+ link: string;
442
+ isoDate?: Date | undefined;
443
+ pubDate?: Date | undefined;
444
+ content?: string | undefined;
445
+ contentSnippet?: string | undefined;
446
+ "content:encoded"?: string | undefined;
447
+ description?: string | undefined;
448
+ }>, {
449
+ title: string;
450
+ link: string;
451
+ date: Date;
452
+ content: string | undefined;
453
+ contentSnippet: string | undefined;
454
+ description: string | undefined;
455
+ "content:encoded": string | undefined;
456
+ }, {
457
+ title: string;
458
+ link: string;
459
+ isoDate?: Date | undefined;
460
+ pubDate?: Date | undefined;
461
+ content?: string | undefined;
462
+ contentSnippet?: string | undefined;
463
+ "content:encoded"?: string | undefined;
464
+ description?: string | undefined;
465
+ }>;
466
+ export {};
467
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,87 @@
1
+ import { z } from "zod/v3";
2
+ /** An RSS source */
3
+ const SourceSchema = z.object({
4
+ /** The URL of an RSS feed */
5
+ url: z.string(),
6
+ /** A title to describe the feed */
7
+ title: z.string().describe("A title for the feed"),
8
+ /** Takes a entry preview and returns whether or not it should be displayed */
9
+ filter: z.function().args(z.string()).returns(z.boolean()).optional(),
10
+ });
11
+ /** Configuration for the cache */
12
+ const CacheConfigurationSchema = z.object({
13
+ /** How long to cache a result for */
14
+ cache_duration_minutes: z.number().default(60),
15
+ /** The location of a file to use as a cache */
16
+ cache_file: z.string().default("cache.json"),
17
+ });
18
+ /** A configuration object with caching possibly configured */
19
+ const ConfigurationSchema = z.object({
20
+ /** A list of sources to fetch */
21
+ sources: SourceSchema.array(),
22
+ /** Return the n latest updates from the source list. */
23
+ number: z.number().default(3),
24
+ /** How many words the preview field should be truncated to in characters after HTML has been sanitized and parsed. */
25
+ truncate: z.number().default(300),
26
+ /** Configuration for the cache */
27
+ cache: CacheConfigurationSchema.optional(),
28
+ /** Randomize the output order */
29
+ shuffle: z.boolean().default(false).optional(),
30
+ });
31
+ /** A configuration object with caching definitely configured */
32
+ export const CachedConfigurationSchema = ConfigurationSchema.extend({
33
+ /** Configuration for the cache */
34
+ cache: CacheConfigurationSchema,
35
+ });
36
+ /** A single entry from an RSS feed */
37
+ const ResultEntrySchema = z.object({
38
+ /** The title of the entry */
39
+ title: z.string(),
40
+ /** A direct link to the entry */
41
+ url: z.string(),
42
+ /** The date of the entry */
43
+ date: z.coerce.date(),
44
+ /** The source the entry is from */
45
+ source: SourceSchema,
46
+ /** A preview of the entry. This may contain sanitized HTML. */
47
+ preview: z.string().optional(),
48
+ });
49
+ /** A list of results */
50
+ export const ResultSchema = z.array(ResultEntrySchema);
51
+ /** A single cache entry */
52
+ export const CacheEntrySchema = z.object({
53
+ /** The time a source was last checked */
54
+ timestamp: z.coerce.date(),
55
+ /** The data from the source */
56
+ data: ResultEntrySchema,
57
+ });
58
+ /** A mapping of source URLs to cache entries */
59
+ export const CacheSchema = z.record(CacheEntrySchema);
60
+ /** The expected format fetched RSS feed entries */
61
+ export const FeedEntrySchema = z
62
+ .object({
63
+ title: z.string(),
64
+ link: z.string(),
65
+ isoDate: z.coerce.date().optional(),
66
+ pubDate: z.coerce.date().optional(),
67
+ content: z.string().optional(),
68
+ contentSnippet: z.string().optional(),
69
+ "content:encoded": z.string().optional(),
70
+ description: z.string().optional(),
71
+ })
72
+ .transform((entry) => {
73
+ const date = entry.isoDate ?? entry.pubDate;
74
+ if (!date) {
75
+ throw new Error("no date found in feed entry");
76
+ }
77
+ return {
78
+ title: entry.title,
79
+ link: entry.link,
80
+ date,
81
+ content: entry.content,
82
+ contentSnippet: entry.contentSnippet,
83
+ description: entry.description,
84
+ "content:encoded": entry["content:encoded"],
85
+ };
86
+ });
87
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/util.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ export declare function asyncMapFilterUndefined<T, U>(input: T[], fn: (x: T) => Promise<U | undefined>): Promise<U[]>;
2
+ export declare function asyncMap<T, U>(input: T[], fn: (x: T) => Promise<U>): Promise<U[]>;
3
+ export declare function filterUndefined<T>(input: (T | undefined)[]): T[];
4
+ //# sourceMappingURL=util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAGA,wBAAsB,uBAAuB,CAAC,CAAC,EAAE,CAAC,EAChD,KAAK,EAAE,CAAC,EAAE,EACV,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,GACnC,OAAO,CAAC,CAAC,EAAE,CAAC,CAGd;AAED,wBAAsB,QAAQ,CAAC,CAAC,EAAE,CAAC,EACjC,KAAK,EAAE,CAAC,EAAE,EACV,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GACvB,OAAO,CAAC,CAAC,EAAE,CAAC,CAOd;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,GAAG,SAAS,CAAC,EAAE,GAAG,CAAC,EAAE,CAQhE"}
package/dist/util.js ADDED
@@ -0,0 +1,20 @@
1
+ import * as R from "remeda";
2
+ // run an async map operation, filtering out undefined results
3
+ export async function asyncMapFilterUndefined(input, fn) {
4
+ const results = await asyncMap(input, fn);
5
+ return filterUndefined(results);
6
+ }
7
+ export async function asyncMap(input, fn) {
8
+ const promises = R.pipe(input, R.map((item) => fn(item)));
9
+ return Promise.all(promises);
10
+ }
11
+ export function filterUndefined(input) {
12
+ const result = [];
13
+ for (const item of input) {
14
+ if (item !== undefined) {
15
+ result.push(item);
16
+ }
17
+ }
18
+ return result;
19
+ }
20
+ //# sourceMappingURL=util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAE5B,8DAA8D;AAC9D,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,KAAU,EACV,EAAoC;IAEpC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC1C,OAAO,eAAe,CAAC,OAAO,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,KAAU,EACV,EAAwB;IAExB,MAAM,QAAQ,GAAG,CAAC,CAAC,IAAI,CACrB,KAAK,EACL,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAC1B,CAAC;IAEF,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,eAAe,CAAI,KAAwB;IACzD,MAAM,MAAM,GAAQ,EAAE,CAAC;IACvB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,72 @@
1
+ {
2
+ "name": "webring",
3
+ "description": "Collect the latest RSS items from your favorite feeds.",
4
+ "author": {
5
+ "name": "Jerred Shepherd",
6
+ "email": "npm@sjer.red",
7
+ "url": "https://sjer.red"
8
+ },
9
+ "homepage": "https://github.com/shepherdjerred/monorepo/tree/main/packages/webring",
10
+ "license": "GPL-3.0-only",
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "https://github.com/shepherdjerred/monorepo.git",
14
+ "directory": "packages/webring"
15
+ },
16
+ "bugs": {
17
+ "url": "https://github.com/shepherdjerred/monorepo/issues"
18
+ },
19
+ "type": "module",
20
+ "version": "0.0.0-dev.706",
21
+ "scripts": {
22
+ "lint": "eslint src --cache",
23
+ "build": "tsc",
24
+ "watch": "tsc -w",
25
+ "test": "bun test src/",
26
+ "test:update": "bun test src/ --update-snapshots",
27
+ "typedoc": "typedoc src/index.ts",
28
+ "typecheck": "tsc --noEmit"
29
+ },
30
+ "main": "dist/index.js",
31
+ "types": "dist/index.d.ts",
32
+ "exports": {
33
+ ".": {
34
+ "types": "./src/index.ts",
35
+ "default": "./dist/index.js"
36
+ }
37
+ },
38
+ "dependencies": {
39
+ "remeda": "^2.21.2",
40
+ "rss-parser": "^3.13.0",
41
+ "sanitize-html": "^2.14.0",
42
+ "truncate-html": "^1.2.0",
43
+ "zod": "^3.24.2"
44
+ },
45
+ "devDependencies": {
46
+ "@shepherdjerred/eslint-config": "^0.2.0",
47
+ "@tsconfig/node24": "^24.0.0",
48
+ "@tsconfig/strictest": "^2.0.5",
49
+ "@types/bun": "^1.3.11",
50
+ "@types/express": "^5.0.0",
51
+ "@types/node": "^25.0.0",
52
+ "@types/sanitize-html": "^2.13.0",
53
+ "eslint": "^9.22.0",
54
+ "express": "^5.0.0",
55
+ "globals": "^17.0.0",
56
+ "jiti": "^2.6.1",
57
+ "typedoc": "^0.28.0",
58
+ "typedoc-plugin-extras": "^4.0.1",
59
+ "typedoc-plugin-zod": "^1.4.0",
60
+ "typescript": "^5.8.2",
61
+ "vitest": "^3.0.8"
62
+ },
63
+ "files": [
64
+ "dist",
65
+ "src",
66
+ "package.json",
67
+ "README.md",
68
+ "LICENSE",
69
+ "bun.lock",
70
+ "CHANGELOG.md"
71
+ ]
72
+ }