Skip to content

API Reference

github-actions[bot] edited this page Jul 28, 2026 · 4 revisions

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

No-throw contract

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.parse in a try/catch; a parse failure becomes an XML_PARSE_ERROR issue on both feed.errors and feed.rss.errors, and this.data is left empty so validate()/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 relative media:content URL resolution are all guarded with URL.canParse before 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/OgetRecipeFromUrl/getHtmlContent (see below) still reject on a genuine network failure or non-ok response — that's a Promise rejection, not a thrown exception from RSSFeed itself, 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.

Error model: FeedIssue

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() / build() lifecycle

  • validate() populates errors/warnings against the tag allow-lists in tag.ts. It does not mutate the parsed input (no delete), and it resets its own accumulators at the start, so calling it more than once is idempotent.
  • build() calls validate() automatically if it hasn't run yet, then constructs the typed RSS. If rss.errors is non-empty after validation, build() returns early with that RSS (no items are built).
  • Both are async even 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.

RSSFeed

import { RSSFeed } from '@canvasflow/feed';

Instance members

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.

Static members

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 / getHtmlContent perform network I/O (fetch); everything else is pure.

Network I/O (src/rss/recipe.ts)

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.

HTMLMapper

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.

Exported helper functions

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.

Type guards

The is* component guards (e.g. isImageComponent, isVideoComponent) and isValidTextRole are exported from the component module — see Component Types.

Exported 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.ts and the files it re-exports.

Clone this wiki locally