Skip to content

Commit 4dca0fe

Browse files
committed
feat(node): add type definitions for all namespaces
Phase 2: Node.js Type Definitions New types (13 total): - GeoLocation (geoType, coordinates, crs) - MediaThumbnail (url, width, height) - MediaContent (url, type, filesize, width, height, duration) - ItunesFeedMeta (author, owner, categories, explicit, image, keywords, podcastType, complete, newFeedUrl) - ItunesOwner (name, email) - ItunesCategory (text, subcategory) - PodcastMeta (transcripts, funding, persons, guid, value) - PodcastFunding (url, message) - PodcastEntryMeta (transcript, chapters, soundbite, person) - PodcastChapters (url, type) - PodcastSoundbite (startTime, duration, title) - PodcastValue (type, method, suggested, recipients) - PodcastValueRecipient (name, type, address, split, fee) Security: SSRF warnings on all URL fields Documentation: Enhanced with format examples and security notes
1 parent 386f617 commit 4dca0fe

File tree

3 files changed

+613
-58
lines changed

3 files changed

+613
-58
lines changed

crates/feedparser-rs-node/index.d.ts

Lines changed: 191 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,24 @@ export interface Generator {
163163
version?: string
164164
}
165165

166+
/** Geographic location from GeoRSS namespace */
167+
export interface GeoLocation {
168+
/** Type of geographic shape ("point", "line", "polygon", "box") */
169+
geoType: string
170+
/**
171+
* Coordinate pairs as nested array [[lat, lng], ...]
172+
*
173+
* Format depends on geo_type:
174+
* - "point": Single pair [[lat, lng]]
175+
* - "line": Two or more pairs [[lat1, lng1], [lat2, lng2], ...]
176+
* - "box": Two pairs [[lower-left-lat, lower-left-lng], [upper-right-lat, upper-right-lng]]
177+
* - "polygon": Three or more pairs forming a closed shape [[lat1, lng1], ..., [lat1, lng1]]
178+
*/
179+
coordinates: Array<Array<number>>
180+
/** Coordinate Reference System (e.g., "EPSG:4326" for WGS84 latitude/longitude) */
181+
crs?: string
182+
}
183+
166184
/** Image metadata */
167185
export interface Image {
168186
/** Image URL */
@@ -179,6 +197,44 @@ export interface Image {
179197
description?: string
180198
}
181199

200+
/** iTunes category */
201+
export interface ItunesCategory {
202+
/** Category text */
203+
text: string
204+
/** Subcategory */
205+
subcategory?: string
206+
}
207+
208+
/** iTunes podcast feed metadata */
209+
export interface ItunesFeedMeta {
210+
/** Podcast author */
211+
author?: string
212+
/** Podcast owner information */
213+
owner?: ItunesOwner
214+
/** Podcast categories */
215+
categories: Array<ItunesCategory>
216+
/** Explicit content flag */
217+
explicit?: boolean
218+
/** Podcast artwork URL */
219+
image?: string
220+
/** Podcast keywords */
221+
keywords: Array<string>
222+
/** Podcast type (episodic/serial) */
223+
podcastType?: string
224+
/** Podcast completion status */
225+
complete?: boolean
226+
/** New feed URL for migrated podcasts */
227+
newFeedUrl?: string
228+
}
229+
230+
/** iTunes owner information */
231+
export interface ItunesOwner {
232+
/** Owner name */
233+
name?: string
234+
/** Owner email */
235+
email?: string
236+
}
237+
182238
/** Link in feed or entry */
183239
export interface Link {
184240
/** Link URL */
@@ -195,6 +251,40 @@ export interface Link {
195251
hreflang?: string
196252
}
197253

254+
/** Media RSS content */
255+
export interface MediaContent {
256+
/**
257+
* Media URL
258+
*
259+
* Note: URL from untrusted feed input. Validate before fetching.
260+
*/
261+
url: string
262+
/** MIME type */
263+
type?: string
264+
/** File size in bytes (converted from u64 with i64::MAX cap) */
265+
filesize?: number
266+
/** Width in pixels */
267+
width?: number
268+
/** Height in pixels */
269+
height?: number
270+
/** Duration in seconds (converted from u64 with i64::MAX cap) */
271+
duration?: number
272+
}
273+
274+
/** Media RSS thumbnail */
275+
export interface MediaThumbnail {
276+
/**
277+
* Thumbnail URL
278+
*
279+
* Note: URL from untrusted feed input. Validate before fetching.
280+
*/
281+
url: string
282+
/** Width in pixels */
283+
width?: number
284+
/** Height in pixels */
285+
height?: number
286+
}
287+
198288
/**
199289
* Parse an RSS/Atom/JSON Feed from bytes or string
200290
*
@@ -341,6 +431,56 @@ export interface Person {
341431
uri?: string
342432
}
343433

434+
/** Podcast chapters */
435+
export interface PodcastChapters {
436+
/**
437+
* Chapters URL
438+
*
439+
* Note: URL from untrusted feed input. Validate before fetching.
440+
*/
441+
url: string
442+
/** Chapters MIME type (e.g., "application/json+chapters", "application/xml+chapters") */
443+
type: string
444+
}
445+
446+
/** Podcast 2.0 episode metadata */
447+
export interface PodcastEntryMeta {
448+
/** Episode transcripts */
449+
transcript: Array<PodcastTranscript>
450+
/** Episode chapters */
451+
chapters?: PodcastChapters
452+
/** Episode soundbites */
453+
soundbite: Array<PodcastSoundbite>
454+
/** Episode persons */
455+
person: Array<PodcastPerson>
456+
}
457+
458+
/** Podcast funding link */
459+
export interface PodcastFunding {
460+
/**
461+
* Funding URL
462+
*
463+
* Note: URL from untrusted feed input. Validate before fetching.
464+
*/
465+
url: string
466+
/** Funding message */
467+
message?: string
468+
}
469+
470+
/** Podcast 2.0 namespace metadata (feed level) */
471+
export interface PodcastMeta {
472+
/** Podcast transcripts */
473+
transcripts: Array<PodcastTranscript>
474+
/** Podcast funding links */
475+
funding: Array<PodcastFunding>
476+
/** Podcast persons (hosts, etc.) */
477+
persons: Array<PodcastPerson>
478+
/** Podcast GUID */
479+
guid?: string
480+
/** Value-for-value payment information */
481+
value?: PodcastValue
482+
}
483+
344484
/** Podcast person metadata */
345485
export interface PodcastPerson {
346486
/** Person's name */
@@ -349,15 +489,37 @@ export interface PodcastPerson {
349489
role?: string
350490
/** Person's group (e.g., "cast", "crew") */
351491
group?: string
352-
/** Person's image URL */
492+
/**
493+
* Person's image URL
494+
*
495+
* Note: URL from untrusted feed input. Validate before fetching.
496+
*/
353497
img?: string
354-
/** Person's URL/website */
498+
/**
499+
* Person's URL/website
500+
*
501+
* Note: URL from untrusted feed input. Validate before fetching.
502+
*/
355503
href?: string
356504
}
357505

506+
/** Podcast soundbite */
507+
export interface PodcastSoundbite {
508+
/** Start time in seconds */
509+
startTime: number
510+
/** Duration in seconds */
511+
duration: number
512+
/** Title */
513+
title?: string
514+
}
515+
358516
/** Podcast transcript metadata */
359517
export interface PodcastTranscript {
360-
/** Transcript URL */
518+
/**
519+
* Transcript URL
520+
*
521+
* Note: URL from untrusted feed input. Validate before fetching.
522+
*/
361523
url: string
362524
/** Transcript type (e.g., "text/plain", "application/srt") */
363525
type?: string
@@ -367,6 +529,32 @@ export interface PodcastTranscript {
367529
rel?: string
368530
}
369531

532+
/** Podcast 2.0 value element for monetization */
533+
export interface PodcastValue {
534+
/** Payment type: "lightning", "hive", etc. */
535+
type: string
536+
/** Payment method: "keysend" for Lightning Network */
537+
method: string
538+
/** Suggested payment amount */
539+
suggested?: string
540+
/** List of payment recipients with split percentages */
541+
recipients: Array<PodcastValueRecipient>
542+
}
543+
544+
/** Value recipient for payment splitting */
545+
export interface PodcastValueRecipient {
546+
/** Recipient's name */
547+
name?: string
548+
/** Recipient type: "node" for Lightning Network nodes */
549+
type: string
550+
/** Payment address (e.g., Lightning node public key) */
551+
address: string
552+
/** Payment split percentage */
553+
split: number
554+
/** Whether this is a fee recipient */
555+
fee?: boolean
556+
}
557+
370558
/** Source reference (for entries) */
371559
export interface Source {
372560
/** Source title */

0 commit comments

Comments
 (0)