-
Notifications
You must be signed in to change notification settings - Fork 0
API Reference
The public surface re-exported from src/index.ts. The two classes you will use most are RSSFeed and HTMLMapper.
← Back to Home · Related: RSS Feeds · HTML Mapping · Component Types
For any string input and any params/root config, new RSSFeed(...),
validate(), and build() never throw — problems are reported through
errors/warnings instead:
-
Malformed XML — the constructor wraps
XMLParser.parsein atry/catch; a parse failure becomes anXML_PARSE_ERRORissue on bothfeed.errorsandfeed.rss.errors, andthis.datais left empty sovalidate()/build()still run to completion. -
Malformed URLs reachable from feed content — the channel
<link>, iframe embeds (YouTube/TikTok/Vimeo/Dailymotion/Twitter/Infogram/Apple Podcasts), anchor-based embeds, and relativemedia:contentURL resolution are all guarded withURL.canParsebefore construction; an unparseable URL becomes a warning or an error-annotated component instead of throwing. -
Invalid
params/root— never silently dropped. The constructor always stores what it's given;build()is the one place that validates them (RSSFeed.validateParams) and reports the result. -
Network I/O —
getRecipeFromUrl/getHtmlContent(see below) still reject on a genuine network failure or non-okresponse — that's aPromiserejection, not a thrown exception fromRSSFeeditself, and is the one place this library performs I/O you didn't explicitly ask for.
Verified by a seeded property-test suite
(src/rss/__tests__/rss-feed.fuzz.test.ts) driving the constructor →
validate() → build() lifecycle over hand-picked edge cases and random
XML/params input. See ADR-0007
(docs/adr/0007-throw-surface-inventory.md) for the full throw-surface
inventory and how each site was fixed.
errors/warnings throughout this library — RSS, Channel, Item,
Enclosure, MediaGroup, MediaContent, RSSFeed.errors,
RSSFeed.validateParams()'s return value, and every Component's
errors/warnings — are arrays of:
interface FeedIssue {
code: FeedIssueCode; // stable string union, exported from '@canvasflow/feed'
severity: 'error' | 'warning';
message: string; // human-readable, for logging/display
path?: string; // e.g. "cf:thumbnail.url", the tag/field the issue is about
}FeedIssueCode is a large, stable, switchable union (XML_PARSE_ERROR,
MISSING_REQUIRED_TAG, INVALID_PARAMS, MISSING_IMAGE_SRC,
INVALID_YOUTUBE_URL, ... — see src/feed-issue.ts for the full list).
Branch on .code for programmatic handling; use .message for display.
See the CHANGELOG's migration guide for the string[] → FeedIssue[]
transition.
-
validate()populateserrors/warningsagainst the tag allow-lists intag.ts. It does not mutate the parsed input (nodelete), and it resets its own accumulators at the start, so calling it more than once is idempotent. -
build()callsvalidate()automatically if it hasn't run yet, then constructs the typedRSS. Ifrss.errorsis non-empty after validation,build()returns early with thatRSS(no items are built). - Both are
asynceven though today's implementation is fully synchronous internally — see ADR-0008 (docs/adr/0008-keep-validate-build-async.md) for why the sync conversion is deferred rather than done now.
import { RSSFeed } from '@canvasflow/feed';| Member | Signature | Description |
|---|---|---|
| constructor | new RSSFeed(content: string, params?: Params) |
Parse the feed XML; optional Params configures HTML conversion. |
content |
string |
The original XML passed in. |
rss |
RSS |
The typed result, populated by validate() / build(). |
errors |
FeedIssue[] |
Top-level errors collected during validation. |
root (setter) |
set root(mapping?: Mapping) |
Scope content extraction to a sub-element before conversion. |
validate() |
Promise<void> |
Validate required tags; fill errors/warnings. |
build() |
Promise<RSS> |
Build the typed RSS; attach a components array to each item. |
| Member | Signature | Description |
|---|---|---|
validateParams |
(params?: Params, root?: Mapping) => FeedIssue[] |
Validate params/root against the Zod schemas; returns structured issues (code is 'INVALID_PARAMS' | 'INVALID_ROOT_MAPPING'). |
toJSON |
(rss: RSS) => unknown |
Serialize then re-parse an RSS (round-trips errors via toString). |
toString |
(rss: RSS) => string |
JSON string of an RSS (Error values are flattened). |
getRecipeFromUrl |
(url: string) => Promise<Recipe | null> |
Deprecated thin wrapper around getRecipeFromUrl from ./recipe (see below). |
getHtmlContent |
(url: string, headers?: HeadersInit) => Promise<string> |
Deprecated thin wrapper around getHtmlContent from ./recipe (see below). |
getRecipeFromUrl/getHtmlContentperform network I/O (fetch); everything else is pure.
Extracted out of RSSFeed (Section 3, "Network I/O extraction") so the
XML-parsing library doesn't hide unbounded fetch calls behind its public
API. Both are exported from @canvasflow/feed directly:
import { getHtmlContent, getRecipeFromUrl } from '@canvasflow/feed';| Function | Signature | Description |
|---|---|---|
getHtmlContent(url, options?) |
(url: string, options?: FetchOptions) => Promise<string> |
Fetch url as text. Rejects on a non-ok response or on exceeding maxBytes. |
getRecipeFromUrl(url, options?) |
(url: string, options?: FetchOptions) => Promise<Recipe | null> |
Fetch url and extract the first LD+JSON Recipe (top-level or nested in @graph); malformed JSON-LD blocks are skipped. |
FetchOptions: { fetch?: typeof fetch; headers?: HeadersInit; timeoutMs?: number /* default 10000 */; maxBytes?: number /* default 5MB */ }. The request is aborted via AbortSignal.timeout(timeoutMs); the response body is read through a size-capped stream.
import { HTMLMapper } from '@canvasflow/feed';| Member | Signature | Description |
|---|---|---|
toComponents |
(html: string, params?: Params) => Component[] |
Convert an HTML string into components. |
getRootElement |
(html: string, mapping: Mapping) => string | null |
Serialize the first element matching mapping. |
splitParagraphImages |
(html: string, tag: string) => string |
Split elements of the given tag that contain <img> so each image becomes its own block. |
See HTML Mapping.
From the mapping module:
| Function | Purpose |
|---|---|
reduceComponents(params?) |
The reducer used by toComponents. |
getRootElement(nodes, mapping) |
Node-level root lookup (the string version lives on HTMLMapper). |
reduceEmptyTextNode, filterEmptyTextNode, mapLivePost
|
Node-tree helpers used by the pipeline. |
processTextLinks(html, link?) |
Rewrite relative/protocol-relative/unsafe links in text HTML. |
isEmpty(content) |
Whether a string is effectively empty (whitespace only). |
isValidMapping(value), isValidParams(value)
|
Boolean validation against the Zod schemas. |
validateParams(value) |
Parse-or-throw, returning a typed Params. |
Constants: textTags, textTagsSet, mappingTagsSet.
The is* component guards (e.g. isImageComponent, isVideoComponent) and isValidTextRole are exported from the component module — see Component Types.
| Group | Types |
|---|---|
| Feed |
RSS, Channel, Item, Enclosure, MediaContent, MediaGroup, Thumbnail
|
| Errors |
FeedIssue, FeedIssueCode, FeedIssueSeverity — see "Error model" above |
| Config |
Params, Mapping, ComponentMapping, MatchType, Filter, TagFilter, ClassFilter, AttributeFilter, AttributeValueFilter, AttributePatternFilter
|
| Component mappings |
ContainerMapping, ColumnsMapping, LiveContainerMapping, RecipeMapping, CustomMapping, TextMapping, GalleryMapping
|
| Components |
Component, ComponentType, TextType, and every *Component interface |
| Schema |
Recipe and related schema types |
Exact signatures are the source of truth — see
src/index.tsand the files it re-exports.
Start here
Reference
Operations