Merge pull request #2464 from Yash-Singh1/jsdoc

Add jsdoc
This commit is contained in:
Knut Sveidqvist 2021-11-11 19:05:21 +01:00 committed by GitHub
commit 1fe31dac7d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 22792 additions and 38115 deletions

2996
dist/mermaid.core.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

57611
dist/mermaid.js vendored

File diff suppressed because one or more lines are too long

2
dist/mermaid.js.map vendored

File diff suppressed because one or more lines are too long

2
dist/mermaid.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1005,7 +1005,7 @@ Note: currentConfig is set in this function
- `conf` the base currentConfig to use as siteConfig - `conf` the base currentConfig to use as siteConfig
Returns **any** the siteConfig Returns **[Object][6]** the siteConfig
## getSiteConfig ## getSiteConfig
@ -1018,7 +1018,7 @@ Returns **any** the siteConfig
**Notes**: **Notes**:
Returns **any** values in siteConfig. Returns **any** values in siteConfig.
Returns **any** Returns **[Object][6]** the siteConfig
## setConfig ## setConfig
@ -1067,6 +1067,14 @@ Note: modifies options in-place
- `options` the potential setConfig parameter - `options` the potential setConfig parameter
## addDirective
Pushes in a directive to the configuration
### Parameters
- `directive` **[Object][6]** The directive to push in
## reset ## reset
## reset ## reset
@ -1185,3 +1193,5 @@ mermaidAPI.initialize({
[4]: 8.6.0_docs.md [4]: 8.6.0_docs.md
[5]: #mermaidapi-configuration-defaults [5]: #mermaidapi-configuration-defaults
[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object

View File

@ -41,6 +41,7 @@ export const updateCurrentConfig = (siteCfg, _directives) => {
currentConfig = cfg; currentConfig = cfg;
return cfg; return cfg;
}; };
/** /**
*## setSiteConfig *## setSiteConfig
*| Function | Description | Type | Values | *| Function | Description | Type | Values |
@ -53,7 +54,7 @@ export const updateCurrentConfig = (siteCfg, _directives) => {
*Note: currentConfig is set in this function *Note: currentConfig is set in this function
**Default value: At default, will mirror Global Config** **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 {*} - the siteConfig * @returns {Object} - the siteConfig
*/ */
export const setSiteConfig = (conf) => { export const setSiteConfig = (conf) => {
siteConfig = assignWithDepth({}, defaultConfig); siteConfig = assignWithDepth({}, defaultConfig);
@ -84,7 +85,7 @@ export const updateSiteConfig = (conf) => {
*| setSiteConfig|Returns the current siteConfig base configuration | Get Request | Returns Any Values in siteConfig| *| setSiteConfig|Returns the current siteConfig base configuration | Get Request | Returns Any Values in siteConfig|
***Notes**: ***Notes**:
*Returns **any** values in siteConfig. *Returns **any** values in siteConfig.
* @returns {*} * @returns {Object} - the siteConfig
*/ */
export const getSiteConfig = () => { export const getSiteConfig = () => {
return assignWithDepth({}, siteConfig); return assignWithDepth({}, siteConfig);
@ -172,6 +173,10 @@ export const sanitize = (options) => {
}); });
}; };
/**
* Pushes in a directive to the configuration
* @param {Object} directive The directive to push in
*/
export const addDirective = (directive) => { export const addDirective = (directive) => {
if (directive.fontFamily) { if (directive.fontFamily) {
if (!directive.themeVariables) { if (!directive.themeVariables) {

View File

@ -25,8 +25,8 @@ const conf = {
/** /**
* Function that adds the vertices found during parsing to the graph to be rendered. * Function that adds the vertices found during parsing to the graph to be rendered.
* @param vert Object containing the vertices. * @param {Object<string, { cssClasses: Array<string>; text: string; id: string; type: string; domId: string; }>} classes Object containing the vertices.
* @param g The graph that is to be drawn. * @param {SVGGElement} g The graph that is to be drawn.
*/ */
export const addClasses = function (classes, g) { export const addClasses = function (classes, g) {
// const svg = select(`[id="${svgId}"]`); // const svg = select(`[id="${svgId}"]`);
@ -226,19 +226,23 @@ export const addRelations = function (relations, g) {
}); });
}; };
// Todo optimize /**
* Gets the ID with the same label as in the cache
* @param {string} label The label to look for
* @returns {string} The resulting ID
*/
const getGraphId = function (label) { const getGraphId = function (label) {
const keys = Object.keys(idCache); const foundEntry = Object.entries(idCache).find((entry) => entry[1].label === label);
for (let i = 0; i < keys.length; i++) { if (foundEntry) {
if (idCache[keys[i]].label === label) { return foundEntry[0];
return keys[i];
}
} }
return undefined;
}; };
/**
* Merges the value of `conf` with the passed `cnf`
* @param {Object} cnf Config to merge
*/
export const setConf = function (cnf) { export const setConf = function (cnf) {
const keys = Object.keys(cnf); const keys = Object.keys(cnf);
@ -249,8 +253,8 @@ export const setConf = function (cnf) {
/** /**
* Draws a flowchart in the tag with id: id based on the graph definition in text. * Draws a flowchart in the tag with id: id based on the graph definition in text.
* @param text * @param {string} text
* @param id * @param {string} id
*/ */
export const drawOld = function (text, id) { export const drawOld = function (text, id) {
idCache = {}; idCache = {};
@ -498,10 +502,11 @@ export const draw = function (text, id) {
// }); // });
}; };
export default { /**
setConf, * Gets the arrow marker for a type index
draw, * @param {number} type The type to look for
}; * @returns {"aggregation" | "extension" | "composition" | "dependency"} The arrow marker
*/
function getArrowMarker(type) { function getArrowMarker(type) {
let marker; let marker;
switch (type) { switch (type) {
@ -522,3 +527,8 @@ function getArrowMarker(type) {
} }
return marker; return marker;
} }
export default {
setConf,
draw,
};

View File

@ -18,21 +18,22 @@ const conf = {
textHeight: 10, textHeight: 10,
}; };
// Todo optimize /**
* Gets the ID with the same label as in the cache
* @param {string} label The label to look for
* @returns {string} The resulting ID
*/
const getGraphId = function (label) { const getGraphId = function (label) {
const keys = Object.keys(idCache); const foundEntry = Object.entries(idCache).find((entry) => entry[1].label === label);
for (let i = 0; i < keys.length; i++) { if (foundEntry) {
if (idCache[keys[i]].label === label) { return foundEntry[0];
return keys[i];
}
} }
return undefined;
}; };
/** /**
* Setup arrow head and define the marker. The result is appended to the svg. * Setup arrow head and define the marker. The result is appended to the svg.
* @param {SVGSVGElement} elem The SVG element to append to
*/ */
const insertMarkers = function (elem) { const insertMarkers = function (elem) {
elem elem
@ -136,6 +137,10 @@ const insertMarkers = function (elem) {
.attr('d', 'M 18,7 L9,13 L14,7 L9,1 Z'); .attr('d', 'M 18,7 L9,13 L14,7 L9,1 Z');
}; };
/**
* Merges the value of `conf` with the passed `cnf`
* @param {Object} cnf Config to merge
*/
export const setConf = function (cnf) { export const setConf = function (cnf) {
const keys = Object.keys(cnf); const keys = Object.keys(cnf);
@ -146,8 +151,8 @@ export const setConf = function (cnf) {
/** /**
* Draws a flowchart in the tag with id: id based on the graph definition in text. * Draws a flowchart in the tag with id: id based on the graph definition in text.
* @param text * @param {string} text
* @param id * @param {string} id
*/ */
export const draw = function (text, id) { export const draw = function (text, id) {
idCache = {}; idCache = {};

View File

@ -144,6 +144,11 @@ export const drawEdge = function (elem, path, relation, conf) {
edgeCount++; edgeCount++;
}; };
/**
* Renders a class diagram
* @param {SVGSVGElement} elem The element to draw it into
* @todo Add more information in the JSDOC here
*/
export const drawClass = function (elem, classDef, conf) { export const drawClass = function (elem, classDef, conf) {
log.info('Rendering class ' + classDef); log.info('Rendering class ' + classDef);
@ -382,6 +387,13 @@ const buildLegacyDisplay = function (text) {
}; };
}; };
/**
* Adds a <tspan> for a member in a diagram
* @param {SVGElement} textEl The element to append to
* @param {string} txt The member
* @param {boolean} isFirst
* @param {{ padding: string; textHeight: string; }} conf The configuration for the member
*/
const addTspan = function (textEl, txt, isFirst, conf) { const addTspan = function (textEl, txt, isFirst, conf) {
let member = parseMember(txt); let member = parseMember(txt);
@ -396,6 +408,14 @@ const addTspan = function (textEl, txt, isFirst, conf) {
} }
}; };
/**
* Makes generics in typescript syntax
* @example <caption>Array of array of strings in typescript syntax</caption>
* // returns "Array<Array<string>>"
* parseGenericTypes("Array~Array~string~~");
* @param {string} text The text to convert
* @returns {string} The converted string
*/
const parseGenericTypes = function (text) { const parseGenericTypes = function (text) {
let cleanedText = text; let cleanedText = text;
@ -409,6 +429,11 @@ const parseGenericTypes = function (text) {
} }
}; };
/**
* Gives the styles for a classifier
* @param {"+" | "-" | "#" | "~" | "*" | "$"} classifier The classifier string
* @returns {string} Styling for the classifier
*/
const parseClassifier = function (classifier) { const parseClassifier = function (classifier) {
switch (classifier) { switch (classifier) {
case '*': case '*':

View File

@ -1,5 +1,10 @@
import DOMPurify from 'dompurify'; import DOMPurify from 'dompurify';
/**
* Gets the number of lines in a string
* @param {string | undefined} s The string to check the lines for
* @returns {number} The number of lines in that string
*/
export const getRows = (s) => { export const getRows = (s) => {
if (!s) return 1; if (!s) return 1;
let str = breakToPlaceholder(s); let str = breakToPlaceholder(s);
@ -7,6 +12,11 @@ export const getRows = (s) => {
return str.split('#br#'); return str.split('#br#');
}; };
/**
* Removes script tags from a text
* @param {string} txt The text to sanitize
* @returns {string} The safer text
*/
export const removeScript = (txt) => { export const removeScript = (txt) => {
var rs = ''; var rs = '';
var idx = 0; var idx = 0;
@ -72,20 +82,47 @@ export const sanitizeText = (text, config) => {
export const lineBreakRegex = /<br\s*\/?>/gi; export const lineBreakRegex = /<br\s*\/?>/gi;
/**
* Whether or not a text has any linebreaks
* @param {string} text The text to test
* @returns {boolean} Whether or not the text has breaks
*/
export const hasBreaks = (text) => { export const hasBreaks = (text) => {
return /<br\s*[/]?>/gi.test(text); return lineBreakRegex.test(text);
}; };
/**
* Splits on <br> tags
* @param {string} text Text to split
* @returns {Array<string>} List of lines as strings
*/
export const splitBreaks = (text) => { export const splitBreaks = (text) => {
return text.split(/<br\s*[/]?>/gi); return text.split(lineBreakRegex);
}; };
/**
* Converts placeholders to linebreaks in HTML
* @param {string} s HTML with placeholders
* @returns {string} HTML with breaks instead of placeholders
*/
const placeholderToBreak = (s) => { const placeholderToBreak = (s) => {
return s.replace(/#br#/g, '<br/>'); return s.replace(/#br#/g, '<br/>');
}; };
/**
* Opposite of `placeholderToBreak`, converts breaks to placeholders
* @param {string} s HTML string
* @returns {string} String with placeholders
*/
const breakToPlaceholder = (s) => { const breakToPlaceholder = (s) => {
return s.replace(lineBreakRegex, '#br#'); return s.replace(lineBreakRegex, '#br#');
}; };
/**
* Gets the current URL
* @param {boolean} useAbsolute Whether to return the absolute URL or not
* @returns {string} The current URL
*/
const getUrl = (useAbsolute) => { const getUrl = (useAbsolute) => {
let url = ''; let url = '';
if (useAbsolute) { if (useAbsolute) {
@ -102,6 +139,11 @@ const getUrl = (useAbsolute) => {
return url; return url;
}; };
/**
* Converts a string/boolean into a boolean
* @param {string | boolean} val String or boolean to convert
* @returns {boolean} The result from the input
*/
export const evaluate = (val) => (val === 'false' || val === false ? false : true); export const evaluate = (val) => (val === 'false' || val === false ? false : true);
export default { export default {

View File

@ -1,3 +1,8 @@
/**
* Returns the styles given options
* @param {{ fontFamily: string; nodeTextColor: string; textColor: string; titleColor: string; mainBkg: string; nodeBorder: string; arrowheadColor: string; lineColor: string; edgeLabelBackground: string; clusterBkg: string; clusterBorder: string; tertiaryColor: string; border2: string; }} options The options for the styles
* @returns {string} The resulting styles
*/
const getStyles = (options) => const getStyles = (options) =>
`.label { `.label {
font-family: ${options.fontFamily}; font-family: ${options.fontFamily};
@ -69,9 +74,9 @@ const getStyles = (options) =>
.cluster span { .cluster span {
color: ${options.titleColor}; color: ${options.titleColor};
} }
// .cluster div { /* .cluster div {
// color: ${options.titleColor}; color: ${options.titleColor};
// } } */
div.mermaidTooltip { div.mermaidTooltip {
position: absolute; position: absolute;

View File

@ -5,6 +5,11 @@ import { select } from 'd3';
import { log } from './logger'; import { log } from './logger';
const conf = {}; const conf = {};
/**
* Merges the value of `conf` with the passed `cnf`
* @param {Object} cnf Config to merge
*/
export const setConf = function (cnf) { export const setConf = function (cnf) {
const keys = Object.keys(cnf); const keys = Object.keys(cnf);
@ -15,8 +20,8 @@ export const setConf = function (cnf) {
/** /**
* 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 id The text for the error
* @param id * @param ver The version
*/ */
export const draw = (id, ver) => { export const draw = (id, ver) => {
try { try {

View File

@ -1,5 +1,12 @@
import moment from 'moment-mini'; import moment from 'moment-mini';
/**
* @typedef {"debug" | "info" | "warn" | "error" | "fatal"} LogLevel A log level
*/
/**
* @type {Object<LogLevel, number>}
*/
export const LEVELS = { export const LEVELS = {
debug: 1, debug: 1,
info: 2, info: 2,
@ -16,6 +23,10 @@ export const log = {
fatal: () => {}, fatal: () => {},
}; };
/**
* Sets a log level
* @param {LogLevel} [level="fatal"] The level to set the logging to
*/
export const setLogLevel = function (level = 'fatal') { export const setLogLevel = function (level = 'fatal') {
if (isNaN(level)) { if (isNaN(level)) {
level = level.toLowerCase(); level = level.toLowerCase();
@ -56,6 +67,11 @@ export const setLogLevel = function (level = 'fatal') {
} }
}; };
/**
* Returns a format with the timestamp and the log level
* @param {LogLevel} level The level for the log format
* @returns {string} The format with the timestamp and log level
*/
const format = (level) => { const format = (level) => {
const time = moment().format('ss.SSS'); const time = moment().format('ss.SSS');
return `%c${time} : ${level} : `; return `%c${time} : ${level} : `;

View File

@ -175,6 +175,7 @@ export const detectDirective = function (text, type = null) {
* ``` * ```
* *
* @param {string} text The text defining the graph * @param {string} text The text defining the graph
* @param {{ class: { defaultRenderer: string } | undefined; state: { defaultRenderer: string } | undefined; flowchart: { defaultRenderer: string } | undefined; }} [cnf]
* @returns {string} A graph definition key * @returns {string} A graph definition key
*/ */
export const detectType = function (text, cnf) { export const detectType = function (text, cnf) {
@ -234,6 +235,12 @@ export const detectType = function (text, cnf) {
return 'flowchart'; return 'flowchart';
}; };
/**
* Caches results of functions based on input
* @param {Function} fn Function to run
* @param {Function} resolver Function that resolves to an ID given arguments the `fn` takes
* @returns {Function} An optimized caching function
*/
const memoize = (fn, resolver) => { const memoize = (fn, resolver) => {
let cache = {}; let cache = {};
return (...args) => { return (...args) => {
@ -262,6 +269,12 @@ export const isSubstringInArray = function (str, arr) {
return -1; return -1;
}; };
/**
* Returns a d3 curve given a curve name
* @param {string | undefined} interpolate The interpolation name
* @param {*} defaultCurve The default curve to return
* @returns {import('d3-shape').CurveFactory} The curve factory to use
*/
export const interpolateToCurve = (interpolate, defaultCurve) => { export const interpolateToCurve = (interpolate, defaultCurve) => {
if (!interpolate) { if (!interpolate) {
return defaultCurve; return defaultCurve;
@ -270,6 +283,12 @@ export const interpolateToCurve = (interpolate, defaultCurve) => {
return d3CurveTypes[curveName] || defaultCurve; return d3CurveTypes[curveName] || defaultCurve;
}; };
/**
* Formats a URL string
* @param {string} linkStr String of the URL
* @param {{ securityLevel: string; }} config Configuration passed to MermaidJS
* @returns {string | undefined} The formatted URL
*/
export const formatUrl = (linkStr, config) => { export const formatUrl = (linkStr, config) => {
let url = linkStr.trim(); let url = linkStr.trim();
@ -282,6 +301,11 @@ export const formatUrl = (linkStr, config) => {
} }
}; };
/**
* Runs a function
* @param {string} functionName A dot seperated path to the function relative to the `window`
* @param {...any} params Parameters to pass to the function
*/
export const runFunc = (functionName, ...params) => { export const runFunc = (functionName, ...params) => {
const arrPaths = functionName.split('.'); const arrPaths = functionName.split('.');
@ -297,9 +321,26 @@ export const runFunc = (functionName, ...params) => {
obj[fnName](...params); obj[fnName](...params);
}; };
/**
* @typedef {Object} Point A (x, y) point
* @property {number} x The x value
* @property {number} y The y value
*/
/**
* Finds the distance between two points using the Distance Formula
* @param {Point} p1 The first point
* @param {Point} p2 The second point
* @returns {number} The distance
*/
const distance = (p1, p2) => const distance = (p1, p2) =>
p1 && p2 ? Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2)) : 0; p1 && p2 ? Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2)) : 0;
/**
* @todo Give this a description
* @param {Array<Point>} points List of points
* @returns {Point}
*/
const traverseEdge = (points) => { const traverseEdge = (points) => {
let prevPoint; let prevPoint;
let totalDistance = 0; let totalDistance = 0;
@ -337,6 +378,11 @@ const traverseEdge = (points) => {
return center; return center;
}; };
/**
* Alias for `traverseEdge`
* @param {Point[]} points List of points
* @returns {Point} Return result of `transverseEdge`
*/
const calcLabelPosition = (points) => { const calcLabelPosition = (points) => {
return traverseEdge(points); return traverseEdge(points);
}; };
@ -462,6 +508,11 @@ const calcTerminalLabelPosition = (terminalMarkerSize, position, _points) => {
return cardinalityPosition; return cardinalityPosition;
}; };
/**
* Gets styles from an array of declarations
* @param {Array<string>} arr Declarations
* @returns {{ style: string; labelStyle: string; }} The styles grouped as strings
*/
export const getStylesFromArray = (arr) => { export const getStylesFromArray = (arr) => {
let style = ''; let style = '';
let labelStyle = ''; let labelStyle = '';
@ -520,9 +571,9 @@ export const random = (options) => {
* <p> * <p>
* If src is a destructured array of objects and dst is not an array, assignWithDepth will apply each element of src to dst * If src is a destructured array of objects and dst is not an array, assignWithDepth will apply each element of src to dst
* in order. * in order.
* @param dst:any - the destination of the merge * @param {any} dst - the destination of the merge
* @param src:any - the source object(s) to merge into destination * @param {any} src - the source object(s) to merge into destination
* @param config:{ depth: number, clobber: boolean } - depth: depth to traverse within src and dst for merging - * @param {{ depth: number, clobber: boolean }} [config={ depth: 2, clobber: false }] - depth: depth to traverse within src and dst for merging -
* clobber: should dissimilar types clobber (default: { depth: 2, clobber: false }) * clobber: should dissimilar types clobber (default: { depth: 2, clobber: false })
* @returns {*} * @returns {*}
*/ */
@ -580,6 +631,12 @@ export const getTextObj = function () {
}; };
}; };
/**
* Adds text to an element
* @param {SVGElement} elem Element to add text to
* @param {{ 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; }} textData
* @returns {SVGTextElement} Text element with given styling and content
*/
export const drawSimpleText = function (elem, textData) { export const drawSimpleText = function (elem, textData) {
// Remove and ignore br:s // Remove and ignore br:s
const nText = textData.text.replace(common.lineBreakRegex, ' '); const nText = textData.text.replace(common.lineBreakRegex, ' ');
@ -770,12 +827,24 @@ export const calculateTextDimensions = memoize(
(text, config) => `${text}-${config.fontSize}-${config.fontWeight}-${config.fontFamily}` (text, config) => `${text}-${config.fontSize}-${config.fontWeight}-${config.fontFamily}`
); );
/**
* Applys d3 attributes
* @param {*} d3Elem d3 Element to apply the attributes onto
* @param {Array<[string, string]>} attrs Object.keys equivalent format of key to value mapping of attributes
*/
const d3Attrs = function (d3Elem, attrs) { const d3Attrs = function (d3Elem, attrs) {
for (let attr of attrs) { for (let attr of attrs) {
d3Elem.attr(attr[0], attr[1]); d3Elem.attr(attr[0], attr[1]);
} }
}; };
/**
* Gives attributes for an SVG's size given arguments
* @param {number} height The height of the SVG
* @param {number} width The width of the SVG
* @param {boolean} useMaxWidth Whether or not to use max-width and set width to 100%
* @returns {Map<'height' | 'width' | 'style', string>} Attributes for the SVG
*/
export const calculateSvgSizeAttrs = function (height, width, useMaxWidth) { export const calculateSvgSizeAttrs = function (height, width, useMaxWidth) {
let attrs = new Map(); let attrs = new Map();
attrs.set('height', height); attrs.set('height', height);
@ -788,6 +857,13 @@ export const calculateSvgSizeAttrs = function (height, width, useMaxWidth) {
return attrs; return attrs;
}; };
/**
* Applies attributes from `calculateSvgSizeAttrs`
* @param {SVGSVGElement} svgElem The SVG Element to configure
* @param {number} height The height of the SVG
* @param {number} width The width of the SVG
* @param {boolean} useMaxWidth Whether or not to use max-width and set width to 100%
*/
export const configureSvgSize = function (svgElem, height, width, useMaxWidth) { export const configureSvgSize = function (svgElem, height, width, useMaxWidth) {
const attrs = calculateSvgSizeAttrs(height, width, useMaxWidth); const attrs = calculateSvgSizeAttrs(height, width, useMaxWidth);
d3Attrs(svgElem, attrs); d3Attrs(svgElem, attrs);
@ -808,8 +884,13 @@ export const initIdGeneratior = class iterator {
} }
}; };
// Source https://github.com/shrpne/entity-decode/blob/master/browser.js
let decoder; let decoder;
/**
* Decodes HTML, source: {@link https://github.com/shrpne/entity-decode/blob/v2.0.1/browser.js}
* @param {string} html HTML as a string
* @returns Unescaped HTML
*/
export const entityDecode = function (html) { export const entityDecode = function (html) {
decoder = decoder || document.createElement('div'); decoder = decoder || document.createElement('div');
// Escape HTML before decoding for HTML Entities // Escape HTML before decoding for HTML Entities
@ -819,6 +900,10 @@ export const entityDecode = function (html) {
return unescape(decoder.textContent); return unescape(decoder.textContent);
}; };
/**
* Sanitizes directive objects
* @param {Object} args Directive's JSON
*/
export const directiveSanitizer = (args) => { export const directiveSanitizer = (args) => {
log.debug('directiveSanitizer called with', args); log.debug('directiveSanitizer called with', args);
if (typeof args === 'object') { if (typeof args === 'object') {