Skip to content

stringList

function stringList(value: unknown): string[];

Read a config field as a list of strings.

Accepts what the surfaces actually send: a list, a bare string (one entry pasted into a list field), null, or nothing. Entries are trimmed and blanks dropped, so a trailing newline in a textarea does not become an empty feed that fails on every run.

Both catalogs learned this the same way, from opposite ends of the same bug. Reading a list field as (config.feeds || []).map(…) throws .map is not a function on a bare string, losing a whole round mid-sync, cursor included. Reading it as const [first] = config.x ?? [] does not throw — it destructures the string’s first CHARACTER, so a pasted-not-picked show uuid became "6" and the run failed against a uuid that looked nothing like what the user typed. The second is worse than the first: it produces a plausible wrong value instead of an error, and the report that comes back is “it can’t find my show”.

A null INSIDE a list is dropped, not coerced. Both catalogs’ copies of this ran the whole entry through String() and then filter(Boolean), which keeps null — because String(null) is the four-character string "null", and that is truthy. A url[] field with a hole in it therefore yielded a feed address of "null", resolved as a relative URL against whatever base the caller used, and failed as a 404 from the source’s own host rather than as the bad config it was. Found by the tests written when this moved here; neither catalog’s copy had a test.

ParameterTypeDescription
valueunknownThe raw config value, as stored.

string[]

Its non-empty entries, trimmed; [] when there are none.

stringList(['https://a.example/feed', ' ']); // ['https://a.example/feed']
stringList('https://a.example/feed'); // ['https://a.example/feed']
stringList(null); // []
stringList(['https://a.example/feed', null]); // ['https://a.example/feed']