2
0
mirror of https://github.com/tenrok/BBob.git synced 2026-05-15 11:59:37 +03:00
Files
bbob/packages/bbob-plugin-helper/src/helpers.ts
T
Nikolay Kost 8797f7f363 feat: typescript support (#185)
* feat: initial typescript support

* feat: typescript support

* feat(plugin-helper): move files to typescript

* chore: update lock files

* feat: preset types

* fix: build

* fix: benchmark

* fix: remove pnpm cache

* fix: bench action

* fix: pnpm recursive install

* fix: nx cache

* fix: lock file

* fix: workflows

* fix: lerna support in pnpm

* fix: pnpm workspace

* fix: remove unused files

* fix: pnpm lock file

* fix: update lerna for support pnpm

* fix: lerna bootstrap

* fix: rollup build

* fix: update nx

* fix: build

* fix: add nx dep target

* fix: remove nx cache

* fix: workflow run on push only for master

* fix: test workflow run on push only for master

* fix: remove parallel for gen types

* fix: benchmark

* fix: benchmark imports

* fix: pnpm

* fix: types errors and pnpm

* fix: types

* fix: types

* refactor: parser

* fix(parser): tests

* fix: preset tests

* fix: react types

* fix: react type declarations

* fix: pnpm lock file

* fix: react preset types

* fix: lock file

* fix: vue2 types

* feat: dev container support

* fix: types

* fix: types

* refactor: rewrite pkg-task, add nx gen-types deps, fix react/render.ts

* refactor: types

* fix: types

* fix: rename gen-types to types

* fix: nx build order

* fix: nx reset

* fix: define nx deps explicit

* fix: build

* fix: nx

* fix: nx order build

* fix: nx deps

* fix: bbob cli tests

* fix: tests

* fix: cli tests and import

* fix: test cover

* fix: cli cover
2024-04-23 21:11:14 +02:00

126 lines
2.9 KiB
TypeScript

import { N } from './char';
import type { TagNode } from "./TagNode";
import type { NodeContent, StringNode } from "./types";
function isTagNode(el: unknown): el is TagNode {
return typeof el === 'object' && el !== null && 'tag' in el;
}
function isStringNode(el: unknown): el is StringNode {
return typeof el === 'string';
}
// check string is end of line
function isEOL(el: string) {
return el === N
}
function keysReduce<Res, Def extends Res, T extends Record<string, unknown>>(obj: T, reduce: (acc: Def, key: keyof T) => Res, def: Def): Res {
const keys = Object.keys(obj)
return keys.reduce((acc, key) => reduce(acc, key), def)
}
function getNodeLength(node: NodeContent): number {
if (isTagNode(node) && Array.isArray(node.content)) {
return node.content.reduce<number>((count, contentNode) => {
return count + getNodeLength(contentNode)
}, 0);
}
if (isStringNode(node)) {
return String(node).length;
}
return 0;
}
function appendToNode(node: TagNode, value: NodeContent) {
if (Array.isArray(node.content)) {
node.content.push(value);
}
}
/**
* Replaces " to &qquot;
* @param {string} value
*/
function escapeAttrValue(value: string) {
return value
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#039;')
// eslint-disable-next-line no-script-url
.replace(/(javascript|data|vbscript):/gi, '$1%3A');
}
/**
* @deprecated use escapeAttrValue
*/
const escapeHTML = escapeAttrValue
/**
* Accept name and value and return valid html5 attribute string
*/
function attrValue<AttrValue = unknown>(name: string, value: AttrValue) {
// in case of performance
switch (typeof value) {
case 'boolean':
return value ? `${name}` : ''
case 'number':
return `${name}="${value}"`
case 'string':
return `${name}="${escapeAttrValue(value as string)}"`
case 'object':
return `${name}="${escapeAttrValue(JSON.stringify(value))}"`
default:
return ''
}
}
/**
* Transforms attrs to html params string
* @example
* attrsToString({ 'foo': true, 'bar': bar' }) => 'foo="true" bar="bar"'
*/
function attrsToString<AttrValue = unknown>(values: Record<string, AttrValue> | null) {
// To avoid some malformed attributes
if (values == null) {
return '';
}
return keysReduce(
values,
(arr, key) => [...arr, attrValue(key, values[key])],
[''],
).join(' ');
}
/**
* Gets value from
* @example
* getUniqAttr({ 'foo': true, 'bar': bar' }) => 'bar'
*/
function getUniqAttr<Value>(attrs: Record<string, Value>) {
return keysReduce(
attrs,
(res, key) => (attrs[key] === key ? attrs[key] : null),
null,
)
}
export {
attrsToString,
attrValue,
appendToNode,
escapeHTML,
escapeAttrValue,
getNodeLength,
getUniqAttr,
isTagNode,
isStringNode,
isEOL,
};