app/lib/publications/entities.mjs
37 lines and 3 functions in DrDustinEdwards/dustinedwards-info, at commit 1590ba4 on 2026-10-24. This file on GitHub.
Functions
| Function | Lines | Complexity | Covered | CRAP | Mutation |
|---|---|---|---|---|---|
| fromCodePoint | 21 to 27 | 6 | 100% | WatchCRAP 6 | No data: no mutants in this code |
| decodeEntities | 33 to 41 | 2 | 100% | OkCRAP 2 | No data: no mutants in this code |
| <anonymous:34> | 34 to 40 | 6 | 100% | WatchCRAP 6 | No data: no mutants in this code |
Imports
It imports no other module of this repo. Imported by app/lib/cv/entries.mjs, app/lib/podcast/feed.mjs, app/lib/publications/article-json-ld.mjs, app/lib/publications/authors.mjs, app/lib/publications/citation-tags.mjs, app/lib/publications/coins.mjs, app/lib/publications/compile.mjs, app/lib/publications/exports.mjs, app/lib/publications/listing.mjs, app/lib/publications/search-inputs.mjs, app/lib/publications/twin.mjs, app/lib/seo.ts, app/routes/home.tsx, app/routes/publications.$slug.tsx, app/routes/publications.tsx.
Source
// Decoded where a person reads it, never at rest: check:machine-readable asserts no stored abstract
// contains <, which keeps registry text safe in JSON-LD and exports. One alternation in one pass, so
// &lt; decodes to < and stops. Unknown names are left verbatim on purpose.
const NAMED = {
amp: "&",
lt: "<",
gt: ">",
quot: '"',
apos: "'",
};
const REFERENCE = /&(?:#(\d+)|#[xX]([0-9a-fA-F]+)|([a-zA-Z][a-zA-Z0-9]*));/g;
/**
* String.fromCodePoint throws out of range, which would fail a render over one bad deposit.
*
* @param {number} code
* @returns {string | null}
*/
function fromCodePoint(code) {
// Zero too: � is a NUL, which no reader should receive from a deposit or a feed.
if (!Number.isInteger(code) || code < 1 || code > 0x10ffff) return null;
// Lone surrogates are valid integers and produce unpaired halves.
if (code >= 0xd800 && code <= 0xdfff) return null;
return String.fromCodePoint(code);
}
/**
* @param {string | null | undefined} text
* @returns {string}
*/
export function decodeEntities(text) {
return String(text ?? "").replace(REFERENCE, (whole, dec, hex, name) => {
if (dec !== undefined) return fromCodePoint(Number(dec)) ?? whole;
if (hex !== undefined) return fromCodePoint(Number.parseInt(hex, 16)) ?? whole;
return Object.prototype.hasOwnProperty.call(NAMED, name)
? /** @type {string} */ (NAMED[/** @type {keyof NAMED} */ (name)])
: whole;
});
}