style: fix eslint-plugin-tsdoc linting issues

Mostly, fixing these eslint-plugin-tsdoc style issues involved:
- Moving types from JSDoc to TypeScript types
- Making sure that all `@param paramName - description`
  had both a `-` and a description.

Occasionally, for some functions, if the JSDoc was completely
empty, I just deleted it, since there was no point in keeping it.
This commit is contained in:
Alois Klink
2022-10-22 13:30:50 +01:00
parent e6f19ff461
commit 7e5689d0b9
15 changed files with 303 additions and 250 deletions

View File

@@ -4,7 +4,7 @@ export const id = 'example-diagram';
/** /**
* Detector function that will be called by mermaid to determine if the diagram is this type of diagram. * Detector function that will be called by mermaid to determine if the diagram is this type of diagram.
* *
* @param txt The diagram text will be passed to the detector * @param txt - The diagram text will be passed to the detector
* @returns True if the diagram text matches a diagram of this type * @returns True if the diagram text matches a diagram of this type
*/ */

View File

@@ -35,18 +35,19 @@ export let setupGraphViewbox: (
/** /**
* Function called by mermaid that injects utility functions that help the diagram to be a good citizen. * Function called by mermaid that injects utility functions that help the diagram to be a good citizen.
* @param _log *
* @param _setLogLevel * @param _log - log from mermaid/src/diagramAPI.ts
* @param _getConfig * @param _setLogLevel - setLogLevel from mermaid/src/diagramAPI.ts
* @param _sanitizeText * @param _getConfig - getConfig from mermaid/src/diagramAPI.ts
* @param _setupGraphViewbox * @param _sanitizeText - sanitizeText from mermaid/src/diagramAPI.ts
* @param _setupGraphViewbox - setupGraphViewbox from mermaid/src/diagramAPI.ts
*/ */
export const injectUtils = ( export const injectUtils = (
_log: Record<keyof typeof LEVELS, typeof console.log>, _log: Record<keyof typeof LEVELS, typeof console.log>,
_setLogLevel: any, _setLogLevel: typeof setLogLevel,
_getConfig: any, _getConfig: typeof getConfig,
_sanitizeText: any, _sanitizeText: typeof sanitizeText,
_setupGraphViewbox: any _setupGraphViewbox: typeof setupGraphViewbox
) => { ) => {
_log.debug('Mermaid utils injected into example-diagram'); _log.debug('Mermaid utils injected into example-diagram');
log.trace = _log.trace; log.trace = _log.trace;

View File

@@ -11,10 +11,7 @@ import Diagram, { type ParseErrorFunction } from '../Diagram';
// Normally, we could just do the following to get the original `parse()` // Normally, we could just do the following to get the original `parse()`
// implementation, however, requireActual returns a promise and it's not documented how to use withing mock file. // implementation, however, requireActual returns a promise and it's not documented how to use withing mock file.
/** /** {@inheritDoc mermaidAPI.parse} */
* @param text
* @param parseError
*/
function parse(text: string, parseError?: ParseErrorFunction): boolean { function parse(text: string, parseError?: ParseErrorFunction): boolean {
addDiagrams(); addDiagrams();
const diagram = new Diagram(text, parseError); const diagram = new Diagram(text, parseError);

View File

@@ -56,7 +56,7 @@ export const updateCurrentConfig = (siteCfg: MermaidConfig, _directives: any[])
* function _Default value: At default, will mirror Global Config_ * function _Default value: At default, will mirror Global Config_
* *
* @param conf - The base currentConfig to use as siteConfig * @param conf - The base currentConfig to use as siteConfig
* @returns {object} - The siteConfig * @returns The new siteConfig
*/ */
export const setSiteConfig = (conf: MermaidConfig): MermaidConfig => { export const setSiteConfig = (conf: MermaidConfig): MermaidConfig => {
siteConfig = assignWithDepth({}, defaultConfig); siteConfig = assignWithDepth({}, defaultConfig);
@@ -91,7 +91,7 @@ export const updateSiteConfig = (conf: MermaidConfig): MermaidConfig => {
* *
* **Notes**: Returns **any** values in siteConfig. * **Notes**: Returns **any** values in siteConfig.
* *
* @returns {object} - The siteConfig * @returns The siteConfig
*/ */
export const getSiteConfig = (): MermaidConfig => { export const getSiteConfig = (): MermaidConfig => {
return assignWithDepth({}, siteConfig); return assignWithDepth({}, siteConfig);
@@ -107,8 +107,8 @@ export const getSiteConfig = (): MermaidConfig => {
* keys. Any values found in conf with key found in siteConfig.secure will be replaced with the * keys. Any values found in conf with key found in siteConfig.secure will be replaced with the
* corresponding siteConfig value. * corresponding siteConfig value.
* *
* @param {any} conf - The potential currentConfig * @param conf - The potential currentConfig
* @returns {any} - The currentConfig merged with the sanitized conf * @returns The currentConfig merged with the sanitized conf
*/ */
export const setConfig = (conf: MermaidConfig): MermaidConfig => { export const setConfig = (conf: MermaidConfig): MermaidConfig => {
// sanitize(conf); // sanitize(conf);
@@ -131,7 +131,7 @@ export const setConfig = (conf: MermaidConfig): MermaidConfig => {
* *
* **Notes**: Returns **any** the currentConfig * **Notes**: Returns **any** the currentConfig
* *
* @returns {any} - The currentConfig * @returns The currentConfig
*/ */
export const getConfig = (): MermaidConfig => { export const getConfig = (): MermaidConfig => {
return assignWithDepth({}, currentConfig); return assignWithDepth({}, currentConfig);
@@ -146,7 +146,7 @@ export const getConfig = (): MermaidConfig => {
* Ensures options parameter does not attempt to override siteConfig secure keys **Notes**: modifies * Ensures options parameter does not attempt to override siteConfig secure keys **Notes**: modifies
* options in-place * options in-place
* *
* @param {any} options - The potential setConfig parameter * @param options - The potential setConfig parameter
*/ */
export const sanitize = (options: any) => { export const sanitize = (options: any) => {
// Checking that options are not in the list of excluded options // Checking that options are not in the list of excluded options
@@ -186,7 +186,7 @@ export const sanitize = (options: any) => {
/** /**
* Pushes in a directive to the configuration * Pushes in a directive to the configuration
* *
* @param {object} directive The directive to push in * @param directive - The directive to push in
*/ */
export const addDirective = (directive: any) => { export const addDirective = (directive: any) => {
if (directive.fontFamily) { if (directive.fontFamily) {
@@ -217,7 +217,8 @@ export const addDirective = (directive: any) => {
* *
* **Notes**: (default: current siteConfig ) (optional, default `getSiteConfig()`) * **Notes**: (default: current siteConfig ) (optional, default `getSiteConfig()`)
* *
* @param config * @param config - base set of values, which currentConfig could be **reset** to.
* Defaults to the current siteConfig (e.g returned by {@link getSiteConfig}).
*/ */
export const reset = (config = siteConfig): void => { export const reset = (config = siteConfig): void => {
// Replace current config with siteConfig // Replace current config with siteConfig

View File

@@ -8,19 +8,27 @@ import { MermaidConfig } from './config.type';
* *
* These are the default options which can be overridden with the initialization call like so: * These are the default options which can be overridden with the initialization call like so:
* *
* **Example 1:**<pre> mermaid.initialize({ flowchart:{ htmlLabels: false } }); </pre> * **Example 1:**
* *
* **Example 2:**<pre> <script> var config = { startOnLoad:true, flowchart:{ useMaxWidth:true, * ```js
* htmlLabels:true, curve:'cardinal', }, * mermaid.initialize({ flowchart:{ htmlLabels: false } });
* ```
* *
* securityLevel:'loose', * **Example 2:**
* *
* }; mermaid.initialize(config); </script> </pre> * ```html
* <script>
* var config = {
* startOnLoad:true,
* flowchart:{ useMaxWidth:true, htmlLabels:true, curve:'cardinal'},
* securityLevel:'loose',
* };
* mermaid.initialize(config);
* </script>
* ```
* *
* A summary of all options and their defaults is found [here](#mermaidapi-configuration-defaults). * A summary of all options and their defaults is found [here](#mermaidapi-configuration-defaults).
* A description of each option follows below. * A description of each option follows below.
*
* @name Configuration
*/ */
const config: Partial<MermaidConfig> = { const config: Partial<MermaidConfig> = {
/** /**
@@ -30,8 +38,16 @@ const config: Partial<MermaidConfig> = {
* | --------- | --------------- | ------ | -------- | ---------------------------------------------- | * | --------- | --------------- | ------ | -------- | ---------------------------------------------- |
* | theme | Built in Themes | string | Optional | 'default', 'forest', 'dark', 'neutral', 'null' | * | theme | Built in Themes | string | Optional | 'default', 'forest', 'dark', 'neutral', 'null' |
* *
* **Notes:** To disable any pre-defined mermaid theme, use "null".<pre> "theme": "forest", * **Notes:** To disable any pre-defined mermaid theme, use "null".
* "themeCSS": ".node rect { fill: red; }" </pre> *
* @example
*
* ```js
* {
* "theme": "forest",
* "themeCSS": ".node rect { fill: red; }"
* }
* ```
*/ */
theme: 'default', theme: 'default',
themeVariables: theme['default'].getThemeVariables(), themeVariables: theme['default'].getThemeVariables(),

View File

@@ -9,10 +9,13 @@ const anyComment = /\s*%%.*\n/gm;
const detectors: Record<string, DetectorRecord> = {}; const detectors: Record<string, DetectorRecord> = {};
/** /**
* @function detectType Detects the type of the graph text. Takes into consideration the possible * Detects the type of the graph text.
* existence of an %%init directive
* *
* ```mermaid * Takes into consideration the possible existence of an `%%init` directive
*
* @param text - The text defining the graph. For example:
*
* ```mermaid
* %%{initialize: {"startOnLoad": true, logLevel: "fatal" }}%% * %%{initialize: {"startOnLoad": true, logLevel: "fatal" }}%%
* graph LR * graph LR
* a-->b * a-->b
@@ -23,13 +26,9 @@ const detectors: Record<string, DetectorRecord> = {};
* f-->g * f-->g
* g-->h * g-->h
* ``` * ```
* @param {string} text The text defining the graph *
* @param {{ * @param config - The mermaid config.
* class: { defaultRenderer: string } | undefined; * @returns A graph definition key
* state: { defaultRenderer: string } | undefined;
* flowchart: { defaultRenderer: string } | undefined;
* }} [config]
* @returns {string} A graph definition key
*/ */
export const detectType = function (text: string, config?: MermaidConfig): string { export const detectType = function (text: string, config?: MermaidConfig): string {
text = text.replace(directive, '').replace(anyComment, '\n'); text = text.replace(directive, '').replace(anyComment, '\n');

View File

@@ -4,8 +4,8 @@ import { MermaidConfig } from '../../config.type';
/** /**
* Gets the rows of lines in a string * Gets the rows of lines in a string
* *
* @param {string | undefined} s The string to check the lines for * @param s - The string to check the lines for
* @returns {string[]} The rows in that string * @returns The rows in that string
*/ */
export const getRows = (s?: string): string[] => { export const getRows = (s?: string): string[] => {
if (!s) { if (!s) {
@@ -18,8 +18,8 @@ export const getRows = (s?: string): string[] => {
/** /**
* Removes script tags from a text * Removes script tags from a text
* *
* @param {string} txt The text to sanitize * @param txt - The text to sanitize
* @returns {string} The safer text * @returns The safer text
*/ */
export const removeScript = (txt: string): string => { export const removeScript = (txt: string): string => {
return DOMPurify.sanitize(txt); return DOMPurify.sanitize(txt);
@@ -68,8 +68,8 @@ export const lineBreakRegex = /<br\s*\/?>/gi;
/** /**
* Whether or not a text has any line breaks * Whether or not a text has any line breaks
* *
* @param {string} text The text to test * @param text - The text to test
* @returns {boolean} Whether or not the text has breaks * @returns Whether or not the text has breaks
*/ */
export const hasBreaks = (text: string): boolean => { export const hasBreaks = (text: string): boolean => {
return lineBreakRegex.test(text); return lineBreakRegex.test(text);
@@ -78,8 +78,8 @@ export const hasBreaks = (text: string): boolean => {
/** /**
* Splits on <br> tags * Splits on <br> tags
* *
* @param {string} text Text to split * @param text - Text to split
* @returns {string[]} List of lines as strings * @returns List of lines as strings
*/ */
export const splitBreaks = (text: string): string[] => { export const splitBreaks = (text: string): string[] => {
return text.split(lineBreakRegex); return text.split(lineBreakRegex);
@@ -88,8 +88,8 @@ export const splitBreaks = (text: string): string[] => {
/** /**
* Converts placeholders to line breaks in HTML * Converts placeholders to line breaks in HTML
* *
* @param {string} s HTML with placeholders * @param s - HTML with placeholders
* @returns {string} HTML with breaks instead of placeholders * @returns HTML with breaks instead of placeholders
*/ */
const placeholderToBreak = (s: string): string => { const placeholderToBreak = (s: string): string => {
return s.replace(/#br#/g, '<br/>'); return s.replace(/#br#/g, '<br/>');
@@ -98,8 +98,8 @@ const placeholderToBreak = (s: string): string => {
/** /**
* Opposite of `placeholderToBreak`, converts breaks to placeholders * Opposite of `placeholderToBreak`, converts breaks to placeholders
* *
* @param {string} s HTML string * @param s - HTML string
* @returns {string} String with placeholders * @returns String with placeholders
*/ */
const breakToPlaceholder = (s: string): string => { const breakToPlaceholder = (s: string): string => {
return s.replace(lineBreakRegex, '#br#'); return s.replace(lineBreakRegex, '#br#');
@@ -108,8 +108,8 @@ const breakToPlaceholder = (s: string): string => {
/** /**
* Gets the current URL * Gets the current URL
* *
* @param {boolean} useAbsolute Whether to return the absolute URL or not * @param useAbsolute - Whether to return the absolute URL or not
* @returns {string} The current URL * @returns The current URL
*/ */
const getUrl = (useAbsolute: boolean): string => { const getUrl = (useAbsolute: boolean): string => {
let url = ''; let url = '';
@@ -130,8 +130,8 @@ const getUrl = (useAbsolute: boolean): string => {
/** /**
* Converts a string/boolean into a boolean * Converts a string/boolean into a boolean
* *
* @param {string | boolean} val String or boolean to convert * @param val - String or boolean to convert
* @returns {boolean} The result from the input * @returns The result from the input
*/ */
export const evaluate = (val?: string | boolean): boolean => export const evaluate = (val?: string | boolean): boolean =>
val === false || ['false', 'null', '0'].includes(String(val).trim().toLowerCase()) ? false : true; val === false || ['false', 'null', '0'].includes(String(val).trim().toLowerCase()) ? false : true;
@@ -139,12 +139,15 @@ export const evaluate = (val?: string | boolean): boolean =>
/** /**
* Makes generics in typescript syntax * Makes generics in typescript syntax
* *
* @example <caption>Array of array of strings in typescript syntax</caption> * @example
* // returns "Array<Array<string>>" * Array of array of strings in typescript syntax
* parseGenericTypes('Array~Array~string~~');
* *
* @param {string} text The text to convert * ```js
* @returns {string} The converted string * // returns "Array<Array<string>>"
* parseGenericTypes('Array~Array~string~~');
* ```
* @param text - The text to convert
* @returns The converted string
*/ */
export const parseGenericTypes = function (text: string): string { export const parseGenericTypes = function (text: string): string {
let cleanedText = text; let cleanedText = text;

View File

@@ -8,7 +8,7 @@ let conf = {};
/** /**
* Merges the value of `conf` with the passed `cnf` * Merges the value of `conf` with the passed `cnf`
* *
* @param {object} cnf Config to merge * @param cnf - Config to merge
*/ */
export const setConf = function (cnf: any) { export const setConf = function (cnf: any) {
conf = { ...conf, ...cnf }; conf = { ...conf, ...cnf };
@@ -17,11 +17,11 @@ export const setConf = function (cnf: any) {
/** /**
* Draws a an info picture in the tag with id: id based on the graph definition in text. * Draws a an info picture in the tag with id: id based on the graph definition in text.
* *
* @param text * @param _text - Mermaid graph definition.
* @param {string} id The text for the error * @param id - The text for the error
* @param {string} mermaidVersion The version * @param mermaidVersion - The version
*/ */
export const draw = (text: string, id: string, mermaidVersion: string) => { export const draw = (_text: string, id: string, mermaidVersion: string) => {
try { try {
log.debug('Renering svg for syntax error\n'); log.debug('Renering svg for syntax error\n');

View File

@@ -10,6 +10,7 @@ import assignWithDepth from '../../assignWithDepth';
import utils from '../../utils'; import utils from '../../utils';
import { configureSvgSize } from '../../setupGraphViewbox'; import { configureSvgSize } from '../../setupGraphViewbox';
import addSVGAccessibilityFields from '../../accessibility'; import addSVGAccessibilityFields from '../../accessibility';
import Diagram from '../../Diagram';
let conf = {}; let conf = {};
@@ -100,8 +101,8 @@ export const bounds = {
// eslint-disable-next-line @typescript-eslint/no-this-alias // eslint-disable-next-line @typescript-eslint/no-this-alias
const _self = this; const _self = this;
let cnt = 0; let cnt = 0;
/** @param {any} type */ /** @param type - Either `activation` or `undefined` */
function updateFn(type) { function updateFn(type?: 'activation') {
return function updateItemBounds(item) { return function updateItemBounds(item) {
cnt++; cnt++;
// The loop sequenceItems is a stack so the biggest margins in the beginning of the sequenceItems // The loop sequenceItems is a stack so the biggest margins in the beginning of the sequenceItems
@@ -200,15 +201,25 @@ export const bounds = {
}, },
}; };
/** Options for drawing a note in {@link drawNote} */
interface NoteModel {
/** x axis start position */
startx: number;
/** y axis position */
starty: number;
/** the message to be shown */
message: string;
/** Set this with a custom width to override the default configured width. */
width: number;
}
/** /**
* Draws an note in the diagram with the attached line * Draws an note in the diagram with the attached line
* *
* @param {any} elem - The diagram to draw to. * @param elem - The diagram to draw to.
* @param {{ x: number; y: number; message: string; width: number }} noteModel - startX: x axis * @param noteModel - Note model options.
* start position, verticalPos: y axis position, message: the message to be shown, width: Set
* this with a custom width to override the default configured width.
*/ */
const drawNote = function (elem, noteModel) { const drawNote = function (elem: any, noteModel: NoteModel) {
bounds.bumpVerticalPos(conf.boxMargin); bounds.bumpVerticalPos(conf.boxMargin);
noteModel.height = conf.boxMargin; noteModel.height = conf.boxMargin;
noteModel.starty = bounds.getVerticalPos(); noteModel.starty = bounds.getVerticalPos();
@@ -278,11 +289,11 @@ const actorFont = (cnf) => {
* message so it can be drawn later. We do not draw the message at this point so the arrowhead can * message so it can be drawn later. We do not draw the message at this point so the arrowhead can
* be on top of the activation box. * be on top of the activation box.
* *
* @param {any} diagram - The parent of the message element * @param _diagram - The parent of the message element.
* @param {any} msgModel - The model containing fields describing a message * @param msgModel - The model containing fields describing a message
* @returns {number} lineStartY - The Y coordinate at which the message line starts * @returns `lineStartY` - The Y coordinate at which the message line starts
*/ */
const boundMessage = function (diagram, msgModel) { function boundMessage(_diagram, msgModel): number {
bounds.bumpVerticalPos(10); bounds.bumpVerticalPos(10);
const { startx, stopx, message } = msgModel; const { startx, stopx, message } = msgModel;
const lines = common.splitBreaks(message).length; const lines = common.splitBreaks(message).length;
@@ -321,17 +332,17 @@ const boundMessage = function (diagram, msgModel) {
bounds.insert(msgModel.fromBounds, msgModel.starty, msgModel.toBounds, msgModel.stopy); bounds.insert(msgModel.fromBounds, msgModel.starty, msgModel.toBounds, msgModel.stopy);
return lineStartY; return lineStartY;
}; }
/** /**
* Draws a message. Note that the bounds have previously been updated by boundMessage. * Draws a message. Note that the bounds have previously been updated by boundMessage.
* *
* @param {any} diagram - The parent of the message element * @param diagram - The parent of the message element
* @param {any} msgModel - The model containing fields describing a message * @param msgModel - The model containing fields describing a message
* @param {number} lineStartY - The Y coordinate at which the message line starts * @param lineStartY - The Y coordinate at which the message line starts
* @param diagObj * @param diagObj - The diagram object.
*/ */
const drawMessage = function (diagram, msgModel, lineStartY, diagObj) { const drawMessage = function (diagram, msgModel, lineStartY: number, diagObj: Diagram) {
const { startx, stopx, starty, message, type, sequenceIndex, sequenceVisible } = msgModel; const { startx, stopx, starty, message, type, sequenceIndex, sequenceVisible } = msgModel;
const textDims = utils.calculateTextDimensions(message, messageFont(conf)); const textDims = utils.calculateTextDimensions(message, messageFont(conf));
const textObj = svgDraw.getTextObj(); const textObj = svgDraw.getTextObj();
@@ -554,13 +565,6 @@ const activationBounds = function (actor, actors) {
return [left, right]; return [left, right];
}; };
/**
* @param {any} loopWidths
* @param {any} msg
* @param {any} preMargin
* @param {any} postMargin
* @param {any} addLoopFn
*/
function adjustLoopHeightForWrap(loopWidths, msg, preMargin, postMargin, addLoopFn) { function adjustLoopHeightForWrap(loopWidths, msg, preMargin, postMargin, addLoopFn) {
bounds.bumpVerticalPos(preMargin); bounds.bumpVerticalPos(preMargin);
let heightAdjust = postMargin; let heightAdjust = postMargin;
@@ -584,12 +588,12 @@ function adjustLoopHeightForWrap(loopWidths, msg, preMargin, postMargin, addLoop
/** /**
* Draws a sequenceDiagram in the tag with id: id based on the graph definition in text. * Draws a sequenceDiagram in the tag with id: id based on the graph definition in text.
* *
* @param {any} _text The text of the diagram * @param _text - The text of the diagram
* @param {any} id The id of the diagram which will be used as a DOM element id¨ * @param id - The id of the diagram which will be used as a DOM element id¨
* @param {any} _version Mermaid version from package.json * @param _version - Mermaid version from package.json
* @param {any} diagObj A standard diagram containing the db and the text and type etc of the diagram * @param diagObj - A standard diagram containing the db and the text and type etc of the diagram
*/ */
export const draw = function (_text, id, _version, diagObj) { export const draw = function (_text: string, id: string, _version: string, diagObj: Diagram) {
const { securityLevel, sequence } = configApi.getConfig(); const { securityLevel, sequence } = configApi.getConfig();
conf = sequence; conf = sequence;
// Handle root and Document for when rendering in sandbox mode // Handle root and Document for when rendering in sandbox mode
@@ -632,10 +636,10 @@ export const draw = function (_text, id, _version, diagObj) {
svgDraw.insertSequenceNumber(diagram); svgDraw.insertSequenceNumber(diagram);
/** /**
* @param {any} msg * @param msg - The message to draw.
* @param {any} verticalPos * @param verticalPos - The vertical position of the message.
*/ */
function activeEnd(msg, verticalPos) { function activeEnd(msg: any, verticalPos: number) {
const activationData = bounds.endActivation(msg); const activationData = bounds.endActivation(msg);
if (activationData.starty + 18 > verticalPos) { if (activationData.starty + 18 > verticalPos) {
activationData.starty = verticalPos - 6; activationData.starty = verticalPos - 6;
@@ -910,12 +914,16 @@ export const draw = function (_text, id, _version, diagObj) {
* It will enumerate each given message, and will determine its text width, in relation to the actor * It will enumerate each given message, and will determine its text width, in relation to the actor
* it originates from, and destined to. * it originates from, and destined to.
* *
* @param {any} actors - The actors map * @param actors - The actors map
* @param {Array} messages - A list of message objects to iterate * @param messages - A list of message objects to iterate
* @param diagObj * @param diagObj - The diagram object.
* @returns {any} * @returns The max message width of each actor.
*/ */
const getMaxMessageWidthPerActor = function (actors, messages, diagObj) { function getMaxMessageWidthPerActor(
actors: { [id: string]: any },
messages: any[],
diagObj: Diagram
): { [id: string]: number } {
const maxMessageWidthPerActor = {}; const maxMessageWidthPerActor = {};
messages.forEach(function (msg) { messages.forEach(function (msg) {
@@ -1008,7 +1016,7 @@ const getMaxMessageWidthPerActor = function (actors, messages, diagObj) {
log.debug('maxMessageWidthPerActor:', maxMessageWidthPerActor); log.debug('maxMessageWidthPerActor:', maxMessageWidthPerActor);
return maxMessageWidthPerActor; return maxMessageWidthPerActor;
}; }
const getRequiredPopupWidth = function (actor) { const getRequiredPopupWidth = function (actor) {
let requiredPopupWidth = 0; let requiredPopupWidth = 0;
@@ -1025,15 +1033,19 @@ const getRequiredPopupWidth = function (actor) {
}; };
/** /**
* This will calculate the optimal margin for each given actor, for a given actor->messageWidth map. * This will calculate the optimal margin for each given actor,
* for a given actor → messageWidth map.
* *
* An actor's margin is determined by the width of the actor, the width of the largest message that * An actor's margin is determined by the width of the actor, the width of the largest message that
* originates from it, and the configured conf.actorMargin. * originates from it, and the configured conf.actorMargin.
* *
* @param {any} actors - The actors map to calculate margins for * @param actors - The actors map to calculate margins for
* @param {any} actorToMessageWidth - A map of actor key -> max message width it holds * @param actorToMessageWidth - A map of actor key max message width it holds
*/ */
const calculateActorMargins = function (actors, actorToMessageWidth) { function calculateActorMargins(
actors: { [id: string]: any },
actorToMessageWidth: ReturnType<typeof getMaxMessageWidthPerActor>
) {
let maxHeight = 0; let maxHeight = 0;
Object.keys(actors).forEach((prop) => { Object.keys(actors).forEach((prop) => {
const actor = actors[prop]; const actor = actors[prop];
@@ -1074,7 +1086,7 @@ const calculateActorMargins = function (actors, actorToMessageWidth) {
} }
return Math.max(maxHeight, conf.height); return Math.max(maxHeight, conf.height);
}; }
const buildNoteModel = function (msg, actors, diagObj) { const buildNoteModel = function (msg, actors, diagObj) {
const startx = actors[msg.from].x; const startx = actors[msg.from].x;

View File

@@ -15,7 +15,7 @@ export const setConf = function (cnf) {
const actors = {}; const actors = {};
/** @param {any} diagram */ /** @param diagram - The diagram to draw to. */
function drawActorLegend(diagram) { function drawActorLegend(diagram) {
const conf = getConfig().journey; const conf = getConfig().journey;
// Draw the actors // Draw the actors
@@ -157,8 +157,8 @@ export const bounds = {
// eslint-disable-next-line @typescript-eslint/no-this-alias // eslint-disable-next-line @typescript-eslint/no-this-alias
const _self = this; const _self = this;
let cnt = 0; let cnt = 0;
/** @param {any} type */ /** @param type - Set to `activation` if activation */
function updateFn(type) { function updateFn(type?: 'activation') {
return function updateItemBounds(item) { return function updateItemBounds(item) {
cnt++; cnt++;
// The loop sequenceItems is a stack so the biggest margins in the beginning of the sequenceItems // The loop sequenceItems is a stack so the biggest margins in the beginning of the sequenceItems

View File

@@ -27,7 +27,7 @@ export const log: Record<keyof typeof LEVELS, typeof console.log> = {
/** /**
* Sets a log level * Sets a log level
* *
* @param {LogLevel} [level="fatal"] The level to set the logging to. Default is `"fatal"` * @param level - The level to set the logging to. Default is `"fatal"`
*/ */
export const setLogLevel = function (level: keyof typeof LEVELS | number | string = 'fatal') { export const setLogLevel = function (level: keyof typeof LEVELS | number | string = 'fatal') {
let numericLevel: number = LEVELS.fatal; let numericLevel: number = LEVELS.fatal;
@@ -80,10 +80,10 @@ export const setLogLevel = function (level: keyof typeof LEVELS | number | strin
/** /**
* Returns a format with the timestamp and the log level * Returns a format with the timestamp and the log level
* *
* @param {LogLevel} level The level for the log format * @param level - The level for the log format
* @returns {string} The format with the timestamp and log level * @returns The format with the timestamp and log level
*/ */
const format = (level: string): string => { const format = (level: Uppercase<LogLevel>): string => {
const time = moment().format('ss.SSS'); const time = moment().format('ss.SSS');
return `%c${time} : ${level} : `; return `%c${time} : ${level} : `;
}; };

View File

@@ -19,12 +19,6 @@ import type { ParseErrorFunction } from './Diagram';
* elements with the attribute already set. This way the init function can be triggered several * elements with the attribute already set. This way the init function can be triggered several
* times. * times.
* *
* Optionally, `init` can accept in the second argument one of the following:
*
* - A DOM Node
* - An array of DOM nodes (as would come from a jQuery selector)
* - A W3C selector, a la `.mermaid`
*
* ```mermaid * ```mermaid
* graph LR; * graph LR;
* a(Find elements)-->b{Processed} * a(Find elements)-->b{Processed}
@@ -34,9 +28,12 @@ import type { ParseErrorFunction } from './Diagram';
* *
* Renders the mermaid diagrams * Renders the mermaid diagrams
* *
* @param config * @param config - **Deprecated**, please set configuration in {@link initialize}.
* @param nodes * @param nodes - **Default**: `.mermaid`. One of the following:
* @param callback * - A DOM Node
* - An array of DOM nodes (as would come from a jQuery selector)
* - A W3C selector, a la `.mermaid`
* @param callback - Called once for each rendered diagram's id.
*/ */
const init = async function ( const init = async function (
config?: MermaidConfig, config?: MermaidConfig,
@@ -202,7 +199,7 @@ if (typeof document !== 'undefined') {
* This is provided for environments where the mermaid object can't directly have a new member added * This is provided for environments where the mermaid object can't directly have a new member added
* to it (eg. dart interop wrapper). (Initially there is no parseError member of mermaid). * to it (eg. dart interop wrapper). (Initially there is no parseError member of mermaid).
* *
* @param {function (err, hash)} newParseErrorHandler New parseError() callback. * @param newParseErrorHandler - New parseError() callback.
*/ */
const setParseErrorHandler = function (newParseErrorHandler: (err: any, hash: any) => void) { const setParseErrorHandler = function (newParseErrorHandler: (err: any, hash: any) => void) {
mermaid.parseError = newParseErrorHandler; mermaid.parseError = newParseErrorHandler;

View File

@@ -9,8 +9,6 @@
* page or do something completely different. * page or do something completely different.
* *
* In addition to the render function, a number of behavioral configuration options are available. * In addition to the render function, a number of behavioral configuration options are available.
*
* @name mermaidAPI
*/ */
import { select } from 'd3'; import { select } from 'd3';
import { compile, serialize, stringify } from 'stylis'; import { compile, serialize, stringify } from 'stylis';
@@ -34,8 +32,8 @@ import { MermaidConfig } from './config.type';
import { evaluate } from './diagrams/common/common'; import { evaluate } from './diagrams/common/common';
/** /**
* @param text * @param text - The mermaid diagram definition.
* @param parseError * @param parseError - If set, handles errors.
*/ */
function parse(text: string, parseError?: ParseErrorFunction): boolean { function parse(text: string, parseError?: ParseErrorFunction): boolean {
addDiagrams(); addDiagrams();
@@ -100,14 +98,13 @@ export const decodeEntities = function (text: string): string {
* }); * });
* ``` * ```
* *
* @param {string} id The id of the element to be rendered * @param id - The id of the element to be rendered
* @param {string} text The graph definition * @param text - The graph definition
* @param {(svgCode: string, bindFunctions?: (element: Element) => void) => void} cb Callback which * @param cb - Callback which is called after rendering is finished with the svg code as param.
* is called after rendering is finished with the svg code as param. * @param container - Selector to element in which a div with the graph temporarily will be
* @param {Element} container Selector to element in which a div with the graph temporarily will be
* inserted. If one is provided a hidden div will be inserted in the body of the page instead. The * inserted. If one is provided a hidden div will be inserted in the body of the page instead. The
* element will be removed when rendering is completed. * element will be removed when rendering is completed.
* @returns {void} * @returns - Resolves when finished rendering.
*/ */
const render = async function ( const render = async function (
id: string, id: string,
@@ -455,7 +452,7 @@ const handleDirective = function (p: any, directive: any, type: string): void {
} }
}; };
/** @param {MermaidConfig} options */ /** @param options - Initial Mermaid options */
async function initialize(options: MermaidConfig) { async function initialize(options: MermaidConfig) {
// Handle legacy location of font-family configuration // Handle legacy location of font-family configuration
if (options?.fontFamily) { if (options?.fontFamily) {

View File

@@ -1,5 +1,5 @@
/** /**
* @file Values that have been hardcoded in src/diagrams/er/styles.js. These can be used by * Values that have been hardcoded in src/diagrams/er/styles.js. These can be used by
* theme-_._ files to maintain display styles until themes, styles, renderers are revised. -- * theme-_._ files to maintain display styles until themes, styles, renderers are revised. --
* 2022-09-22 * 2022-09-22
*/ */

View File

@@ -4,6 +4,7 @@ import {
curveBasis, curveBasis,
curveBasisClosed, curveBasisClosed,
curveBasisOpen, curveBasisOpen,
CurveFactory,
curveLinear, curveLinear,
curveLinearClosed, curveLinearClosed,
curveMonotoneX, curveMonotoneX,
@@ -42,13 +43,13 @@ const directiveWithoutOpen =
/\s*(?:(?:(\w+)(?=:):|(\w+))\s*(?:(?:(\w+))|((?:(?![}][%]{2}).|\r?\n)*))?\s*)(?:[}][%]{2})?/gi; /\s*(?:(?:(\w+)(?=:):|(\w+))\s*(?:(?:(\w+))|((?:(?![}][%]{2}).|\r?\n)*))?\s*)(?:[}][%]{2})?/gi;
/** /**
* @function detectInit Detects the init config object from the text * Detects the init config object from the text
* @param config
* *
* ```mermaid * @param text - The text defining the graph. For example:
* *
* %%{init: {"theme": "debug", "logLevel": 1 }}%% * ```mermaid
* graph LR * %%{init: {"theme": "debug", "logLevel": 1 }}%%
* graph LR
* a-->b * a-->b
* b-->c * b-->c
* c-->d * c-->d
@@ -58,11 +59,11 @@ const directiveWithoutOpen =
* g-->h * g-->h
* ``` * ```
* *
* Or * Or
* *
* ```mermaid * ```mermaid
* %%{initialize: {"theme": "dark", logLevel: "debug" }}%% * %%{initialize: {"theme": "dark", logLevel: "debug" }}%%
* graph LR * graph LR
* a-->b * a-->b
* b-->c * b-->c
* c-->d * c-->d
@@ -71,8 +72,9 @@ const directiveWithoutOpen =
* f-->g * f-->g
* g-->h * g-->h
* ``` * ```
* @param {string} text The text defining the graph *
* @returns {object} The json object representing the init passed to mermaid.initialize() * @param config - Optional mermaid configuration object.
* @returns The json object representing the init passed to mermaid.initialize()
*/ */
export const detectInit = function (text: string, config?: MermaidConfig): MermaidConfig { export const detectInit = function (text: string, config?: MermaidConfig): MermaidConfig {
const inits = detectDirective(text, /(?:init\b)|(?:initialize\b)/); const inits = detectDirective(text, /(?:init\b)|(?:initialize\b)/);
@@ -104,12 +106,14 @@ export const detectInit = function (text: string, config?: MermaidConfig): Merma
}; };
/** /**
* @function detectDirective Detects the directive from the text. Text can be single line or * Detects the directive from the text.
* multiline. If type is null or omitted the first directive encountered in text will be returned
* *
* ```mermaid * Text can be single line or multiline. If type is null or omitted,
* graph LR * the first directive encountered in text will be returned
* %%{someDirective}%% *
* ```mermaid
* graph LR
* %%{someDirective}%%
* a-->b * a-->b
* b-->c * b-->c
* c-->d * c-->d
@@ -118,13 +122,16 @@ export const detectInit = function (text: string, config?: MermaidConfig): Merma
* f-->g * f-->g
* g-->h * g-->h
* ``` * ```
* @param {string} text The text defining the graph *
* @param {string | RegExp} type The directive to return (default: null) * @param text - The text defining the graph
* @returns {object | Array} An object or Array representing the directive(s): { type: string, args: * @param type - The directive to return (default: `null`)
* object|null } matched by the input type if a single directive was found, that directive object * @returns An object or Array representing the directive(s) matched by the input type.
* will be returned. * If a single directive was found, that directive object will be returned.
*/ */
export const detectDirective = function (text, type = null) { export const detectDirective = function (
text: string,
type: string | RegExp = null
): { type?: string; args?: any } | { type?: string; args?: any }[] {
try { try {
const commentWithoutDirectives = new RegExp( const commentWithoutDirectives = new RegExp(
`[%]{2}(?![{]${directiveWithoutOpen.source})(?=[}][%]{2}).*\n`, `[%]{2}(?![{]${directiveWithoutOpen.source})(?=[}][%]{2}).*\n`,
@@ -166,12 +173,13 @@ export const detectDirective = function (text, type = null) {
}; };
/** /**
* @function isSubstringInArray Detects whether a substring in present in a given array * Detects whether a substring in present in a given array
* @param {string} str The substring to detect *
* @param {Array} arr The array to search * @param str - The substring to detect
* @returns {number} The array index containing the substring or -1 if not present * @param arr - The array to search
* @returns The array index containing the substring or -1 if not present
*/ */
export const isSubstringInArray = function (str, arr) { export const isSubstringInArray = function (str: string, arr: string[]): number {
for (let i = 0; i < arr.length; i++) { for (let i = 0; i < arr.length; i++) {
if (arr[i].match(str)) { if (arr[i].match(str)) {
return i; return i;
@@ -183,26 +191,26 @@ export const isSubstringInArray = function (str, arr) {
/** /**
* Returns a d3 curve given a curve name * Returns a d3 curve given a curve name
* *
* @param {string | undefined} interpolate The interpolation name * @param interpolate - The interpolation name
* @param {any} defaultCurve The default curve to return * @param defaultCurve - The default curve to return
* @returns {import('d3-shape').CurveFactory} The curve factory to use * @returns The curve factory to use
*/ */
export const interpolateToCurve = (interpolate, defaultCurve) => { export function interpolateToCurve(interpolate?: string, defaultCurve: CurveFactory): CurveFactory {
if (!interpolate) { if (!interpolate) {
return defaultCurve; return defaultCurve;
} }
const curveName = `curve${interpolate.charAt(0).toUpperCase() + interpolate.slice(1)}`; const curveName = `curve${interpolate.charAt(0).toUpperCase() + interpolate.slice(1)}`;
return d3CurveTypes[curveName] || defaultCurve; return d3CurveTypes[curveName] || defaultCurve;
}; }
/** /**
* Formats a URL string * Formats a URL string
* *
* @param {string} linkStr String of the URL * @param linkStr - String of the URL
* @param {{ securityLevel: string }} config Configuration passed to MermaidJS * @param config - Configuration passed to MermaidJS
* @returns {string | undefined} The formatted URL * @returns The formatted URL or `undefined`.
*/ */
export const formatUrl = (linkStr, config) => { export function formatUrl(linkStr: string, config: { securityLevel: string }): string | undefined {
const url = linkStr.trim(); const url = linkStr.trim();
if (url) { if (url) {
@@ -212,15 +220,15 @@ export const formatUrl = (linkStr, config) => {
return url; return url;
} }
}; }
/** /**
* Runs a function * Runs a function
* *
* @param {string} functionName A dot separated path to the function relative to the `window` * @param functionName - A dot separated path to the function relative to the `window`
* @param {...any} params Parameters to pass to the function * @param params - Parameters to pass to the function
*/ */
export const runFunc = (functionName, ...params) => { export const runFunc = (functionName: string, ...params) => {
const arrPaths = functionName.split('.'); const arrPaths = functionName.split('.');
const len = arrPaths.length - 1; const len = arrPaths.length - 1;
@@ -237,28 +245,31 @@ export const runFunc = (functionName, ...params) => {
obj[fnName](...params); obj[fnName](...params);
}; };
/** /** A (x, y) point */
* @typedef {object} Point A (x, y) point interface Point {
* @property {number} x The x value /** The x value */
* @property {number} y The y value x: number;
*/ /** The y value */
y: number;
}
/** /**
* Finds the distance between two points using the Distance Formula * Finds the distance between two points using the Distance Formula
* *
* @param {Point} p1 The first point * @param p1 - The first point
* @param {Point} p2 The second point * @param p2 - The second point
* @returns {number} The distance * @returns The distance between the two points.
*/ */
const distance = (p1, p2) => function distance(p1: Point, p2: Point): number {
p1 && p2 ? Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2)) : 0; return p1 && p2 ? Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2)) : 0;
}
/** /**
* @param {Point[]} points List of points * TODO: Give this a description
* @returns {Point} *
* @todo Give this a description * @param points - List of points
*/ */
const traverseEdge = (points) => { function traverseEdge(points: Point[]): Point {
let prevPoint; let prevPoint;
let totalDistance = 0; let totalDistance = 0;
@@ -297,20 +308,17 @@ const traverseEdge = (points) => {
prevPoint = point; prevPoint = point;
}); });
return center; return center;
}; }
/** /**
* Alias for `traverseEdge` * {@inheritdoc traverseEdge}
*
* @param {Point[]} points List of points
* @returns {Point} Return result of `transverseEdge`
*/ */
const calcLabelPosition = (points) => { function calcLabelPosition(points: Point[]): Point {
if (points.length === 1) { if (points.length === 1) {
return points[0]; return points[0];
} }
return traverseEdge(points); return traverseEdge(points);
}; }
const calcCardinalityPosition = (isRelationTypePresent, points, initialPosition) => { const calcCardinalityPosition = (isRelationTypePresent, points, initialPosition) => {
let prevPoint; let prevPoint;
@@ -366,14 +374,18 @@ const calcCardinalityPosition = (isRelationTypePresent, points, initialPosition)
}; };
/** /**
* Position ['start_left', 'start_right', 'end_left', 'end_right'] * Calculates the terminal label position.
* *
* @param {any} terminalMarkerSize * @param terminalMarkerSize - Terminal marker size.
* @param {any} position * @param position - Position of label relative to points.
* @param {any} _points * @param _points - Array of points.
* @returns {any} * @returns - The `cardinalityPosition`.
*/ */
const calcTerminalLabelPosition = (terminalMarkerSize, position, _points) => { function calcTerminalLabelPosition(
terminalMarkerSize: number,
position: 'start_left' | 'start_right' | 'end_left' | 'end_right',
_points: Point[]
): Point {
// Todo looking to faster cloning method // Todo looking to faster cloning method
let points = JSON.parse(JSON.stringify(_points)); let points = JSON.parse(JSON.stringify(_points));
let prevPoint; let prevPoint;
@@ -441,15 +453,15 @@ const calcTerminalLabelPosition = (terminalMarkerSize, position, _points) => {
cardinalityPosition.y = -Math.cos(angle) * d + (points[0].y + center.y) / 2 - 5; cardinalityPosition.y = -Math.cos(angle) * d + (points[0].y + center.y) / 2 - 5;
} }
return cardinalityPosition; return cardinalityPosition;
}; }
/** /**
* Gets styles from an array of declarations * Gets styles from an array of declarations
* *
* @param {string[]} arr Declarations * @param arr - Declarations
* @returns {{ style: string; labelStyle: string }} The styles grouped as strings * @returns The styles grouped as strings
*/ */
export const getStylesFromArray = (arr) => { export function getStylesFromArray(arr: string[]): { style: string; labelStyle: string } {
let style = ''; let style = '';
let labelStyle = ''; let labelStyle = '';
@@ -465,7 +477,7 @@ export const getStylesFromArray = (arr) => {
} }
return { style: style, labelStyle: labelStyle }; return { style: style, labelStyle: labelStyle };
}; }
let cnt = 0; let cnt = 0;
export const generateId = () => { export const generateId = () => {
@@ -474,10 +486,12 @@ export const generateId = () => {
}; };
/** /**
* @param {any} length * Generates a random hexadecimal id of the given length.
* @returns {any} *
* @param length - Length of ID.
* @returns The generated ID.
*/ */
function makeid(length) { function makeid(length: number): string {
let result = ''; let result = '';
const characters = '0123456789abcdef'; const characters = '0123456789abcdef';
const charactersLength = characters.length; const charactersLength = characters.length;
@@ -510,22 +524,25 @@ export const getTextObj = function () {
/** /**
* Adds text to an element * Adds text to an element
* *
* @param {SVGElement} elem Element to add text to * @param elem - SVG Element to add text to
* @param {{ * @param textData - Text options.
* text: string; * @returns Text element with given styling and content
* x: number;
* y: number;
* anchor: 'start' | 'middle' | 'end';
* fontFamily: string;
* fontSize: string | number;
* fontWeight: string | number;
* fill: string;
* class: string | undefined;
* textMargin: number;
* }} textData
* @returns {SVGTextElement} Text element with given styling and content
*/ */
export const drawSimpleText = function (elem, textData) { export const drawSimpleText = function (
elem: SVGElement,
textData: {
text: string;
x: number;
y: number;
anchor: 'start' | 'middle' | 'end';
fontFamily: string;
fontSize: string | number;
fontWeight: string | number;
fill: string;
class: string | undefined;
textMargin: number;
}
): SVGTextElement {
// Remove and ignore br:s // Remove and ignore br:s
const nText = textData.text.replace(common.lineBreakRegex, ' '); const nText = textData.text.replace(common.lineBreakRegex, ' ');
@@ -623,43 +640,56 @@ const breakString = memoize(
* *
* If the wrapped text text has greater height, we extend the height, so it's value won't overflow. * If the wrapped text text has greater height, we extend the height, so it's value won't overflow.
* *
* @param {any} text The text to measure * @param text - The text to measure
* @param {any} config - The config for fontSize, fontFamily, and fontWeight all impacting the * @param config - The config for fontSize, fontFamily, and fontWeight all impacting the
* resulting size * resulting size
* @returns {any} - The height for the given text * @returns The height for the given text
*/ */
export const calculateTextHeight = function (text, config) { export function calculateTextHeight(
text: Parameters<typeof calculateTextDimensions>[0],
config: Parameters<typeof calculateTextDimensions>[1]
): ReturnType<typeof calculateTextDimensions>['height'] {
config = Object.assign( config = Object.assign(
{ fontSize: 12, fontWeight: 400, fontFamily: 'Arial', margin: 15 }, { fontSize: 12, fontWeight: 400, fontFamily: 'Arial', margin: 15 },
config config
); );
return calculateTextDimensions(text, config).height; return calculateTextDimensions(text, config).height;
}; }
/** /**
* This calculates the width of the given text, font size and family. * This calculates the width of the given text, font size and family.
* *
* @param {any} text - The text to calculate the width of * @param text - The text to calculate the width of
* @param {any} config - The config for fontSize, fontFamily, and fontWeight all impacting the * @param config - The config for fontSize, fontFamily, and fontWeight all impacting the
* resulting size * resulting size
* @returns {any} - The width for the given text * @returns The width for the given text
*/ */
export const calculateTextWidth = function (text, config) { export function calculateTextWidth(
text: Parameters<typeof calculateTextDimensions>[0],
config: Parameters<typeof calculateTextDimensions>[1]
): ReturnType<typeof calculateTextDimensions>['width'] {
config = Object.assign({ fontSize: 12, fontWeight: 400, fontFamily: 'Arial' }, config); config = Object.assign({ fontSize: 12, fontWeight: 400, fontFamily: 'Arial' }, config);
return calculateTextDimensions(text, config).width; return calculateTextDimensions(text, config).width;
}; }
/** /**
* This calculates the dimensions of the given text, font size, font family, font weight, and * This calculates the dimensions of the given text, font size, font family, font weight, and
* margins. * margins.
* *
* @param {any} text - The text to calculate the width of * @param text - The text to calculate the width of
* @param {any} config - The config for fontSize, fontFamily, fontWeight, and margin all impacting * @param config - The config for fontSize, fontFamily, fontWeight, and margin all impacting
* the resulting size * the resulting size
* @returns - The width for the given text * @returns The dimensions for the given text
*/ */
export const calculateTextDimensions = memoize( export const calculateTextDimensions = memoize(
function (text, config) { function (
text: string,
config: {
fontSize?: number;
fontWeight?: number;
fontFamily?: string;
}
) {
config = Object.assign({ fontSize: 12, fontWeight: 400, fontFamily: 'Arial' }, config); config = Object.assign({ fontSize: 12, fontWeight: 400, fontFamily: 'Arial' }, config);
const { fontSize, fontFamily, fontWeight } = config; const { fontSize, fontFamily, fontWeight } = config;
if (!text) { if (!text) {
@@ -741,10 +771,10 @@ let decoder;
/** /**
* Decodes HTML, source: {@link https://github.com/shrpne/entity-decode/blob/v2.0.1/browser.js} * Decodes HTML, source: {@link https://github.com/shrpne/entity-decode/blob/v2.0.1/browser.js}
* *
* @param {string} html HTML as a string * @param html - HTML as a string
* @returns {string} Unescaped HTML * @returns Unescaped HTML
*/ */
export const entityDecode = function (html) { export const entityDecode = function (html: string): string {
decoder = decoder || document.createElement('div'); decoder = decoder || document.createElement('div');
// Escape HTML before decoding for HTML Entities // Escape HTML before decoding for HTML Entities
html = escape(html).replace(/%26/g, '&').replace(/%23/g, '#').replace(/%3B/g, ';'); html = escape(html).replace(/%26/g, '&').replace(/%23/g, '#').replace(/%3B/g, ';');
@@ -756,9 +786,9 @@ export const entityDecode = function (html) {
/** /**
* Sanitizes directive objects * Sanitizes directive objects
* *
* @param {object} args Directive's JSON * @param args - Directive's JSON
*/ */
export const directiveSanitizer = (args) => { export const directiveSanitizer = (args: any) => {
log.debug('directiveSanitizer called with', args); log.debug('directiveSanitizer called with', args);
if (typeof args === 'object') { if (typeof args === 'object') {
// check for array // check for array
@@ -845,12 +875,12 @@ export interface DetailedError {
hash: any; hash: any;
} }
/** @param error */ /** @param error - The error to check */
export function isDetailedError(error: unknown): error is DetailedError { export function isDetailedError(error: unknown): error is DetailedError {
return 'str' in error; return 'str' in error;
} }
/** @param error */ /** @param error - The error to convert to an error message */
export function getErrorMessage(error: unknown): string { export function getErrorMessage(error: unknown): string {
if (error instanceof Error) { if (error instanceof Error) {
return error.message; return error.message;