mirror of
https://github.com/tenrok/BBob.git
synced 2026-06-20 20:00:33 +03:00
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
This commit is contained in:
@@ -2,3 +2,6 @@ coverage
|
||||
dist
|
||||
lib
|
||||
es
|
||||
types
|
||||
test/*.d.ts
|
||||
test/*.map
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package-lock.json
|
||||
pnpm-lock.yaml
|
||||
coverage
|
||||
src
|
||||
!dist
|
||||
|
||||
@@ -8,17 +8,28 @@
|
||||
"bbob"
|
||||
],
|
||||
"dependencies": {
|
||||
"@bbob/plugin-helper": "workspace:*",
|
||||
"@bbob/preset": "workspace:*"
|
||||
"@bbob/plugin-helper": "*",
|
||||
"@bbob/preset": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@bbob/html": "workspace:*"
|
||||
"@bbob/core": "*",
|
||||
"@bbob/html": "*"
|
||||
},
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
"jsnext:main": "es/index.js",
|
||||
"browser": "dist/index.js",
|
||||
"browserName": "BbobPresetHTML5",
|
||||
"types": "types/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./types/index.d.ts",
|
||||
"import": "./es/index.js",
|
||||
"require": "./lib/index.js",
|
||||
"browser": "./dist/index.min.js",
|
||||
"umd": "./dist/index.min.js"
|
||||
}
|
||||
},
|
||||
"homepage": "https://github.com/JiLiZART/bbob",
|
||||
"author": "Nikolay Kostyurin <jilizart@gmail.com>",
|
||||
"license": "MIT",
|
||||
@@ -30,19 +41,22 @@
|
||||
"url": "git://github.com/JiLiZART/bbob.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build:commonjs": "../../scripts/pkg-task build-commonjs",
|
||||
"build:es": "../../scripts/pkg-task build-es",
|
||||
"build:umd": "../../scripts/pkg-task build-umd",
|
||||
"build": "npm run build:commonjs && npm run build:es && npm run build:umd",
|
||||
"test": "../../scripts/pkg-task test",
|
||||
"cover": "../../scripts/pkg-task cover",
|
||||
"lint": "../../scripts/pkg-task lint",
|
||||
"size": "../../scripts/pkg-task size",
|
||||
"bundlesize": "../../scripts/pkg-task bundlesize"
|
||||
"build:commonjs": "pkg-task",
|
||||
"build:es": "pkg-task",
|
||||
"build:umd": "pkg-task",
|
||||
"build": "pkg-task",
|
||||
"test": "pkg-task",
|
||||
"cover": "pkg-task",
|
||||
"lint": "pkg-task",
|
||||
"size": "pkg-task",
|
||||
"bundlesize": "pkg-task",
|
||||
"types": "pkg-task",
|
||||
"prepublishOnly": "npm run build"
|
||||
},
|
||||
"size-limit": [
|
||||
{
|
||||
"path": "lib/index.js"
|
||||
"path": "./dist/index.min.js",
|
||||
"size": "2.6 KB"
|
||||
}
|
||||
],
|
||||
"bundlesize": [
|
||||
|
||||
+3
@@ -13,6 +13,9 @@ dependencies:
|
||||
version: link:../bbob-preset
|
||||
|
||||
devDependencies:
|
||||
'@bbob/core':
|
||||
specifier: workspace:*
|
||||
version: link:../bbob-core
|
||||
'@bbob/html':
|
||||
specifier: workspace:*
|
||||
version: link:../bbob-html
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
/* eslint-disable no-plusplus,no-lonely-if */
|
||||
import {
|
||||
getUniqAttr, isStringNode, isTagNode, TagNode,
|
||||
} from '@bbob/plugin-helper';
|
||||
|
||||
const isStartsWith = (node, type) => (node[0] === type);
|
||||
|
||||
const styleMap = {
|
||||
color: (val) => `color:${val};`,
|
||||
size: (val) => `font-size:${val};`,
|
||||
};
|
||||
|
||||
const getStyleFromAttrs = (attrs) => Object
|
||||
.keys(attrs)
|
||||
.reduce((acc, key) => (styleMap[key] ? acc.concat(styleMap[key](attrs[key])) : acc), [])
|
||||
.join(' ');
|
||||
|
||||
const asListItems = (content) => {
|
||||
let listIdx = 0;
|
||||
const listItems = [];
|
||||
|
||||
const createItemNode = () => TagNode.create('li');
|
||||
const ensureListItem = (val) => {
|
||||
listItems[listIdx] = listItems[listIdx] || val;
|
||||
};
|
||||
const addItem = (val) => {
|
||||
if (listItems[listIdx] && listItems[listIdx].content) {
|
||||
listItems[listIdx].content = listItems[listIdx].content.concat(val);
|
||||
} else {
|
||||
listItems[listIdx] = listItems[listIdx].concat(val);
|
||||
}
|
||||
};
|
||||
|
||||
content.forEach((el) => {
|
||||
if (isStringNode(el) && isStartsWith(el, '*')) {
|
||||
if (listItems[listIdx]) {
|
||||
listIdx++;
|
||||
}
|
||||
ensureListItem(createItemNode());
|
||||
addItem(el.substr(1));
|
||||
} else if (isTagNode(el) && TagNode.isOf(el, '*')) {
|
||||
if (listItems[listIdx]) {
|
||||
listIdx++;
|
||||
}
|
||||
ensureListItem(createItemNode());
|
||||
} else if (!isTagNode(listItems[listIdx])) {
|
||||
listIdx++;
|
||||
ensureListItem(el);
|
||||
} else if (listItems[listIdx]) {
|
||||
addItem(el);
|
||||
} else {
|
||||
ensureListItem(el);
|
||||
}
|
||||
});
|
||||
|
||||
return [].concat(listItems);
|
||||
};
|
||||
|
||||
const renderUrl = (node, render) => (getUniqAttr(node.attrs)
|
||||
? getUniqAttr(node.attrs)
|
||||
: render(node.content));
|
||||
|
||||
const toNode = (tag, attrs, content) => ({
|
||||
tag,
|
||||
attrs,
|
||||
content,
|
||||
});
|
||||
|
||||
const toStyle = (style) => ({ style });
|
||||
|
||||
export default {
|
||||
b: (node) => toNode('span', toStyle('font-weight: bold;'), node.content),
|
||||
i: (node) => toNode('span', toStyle('font-style: italic;'), node.content),
|
||||
u: (node) => toNode('span', toStyle('text-decoration: underline;'), node.content),
|
||||
s: (node) => toNode('span', toStyle('text-decoration: line-through;'), node.content),
|
||||
url: (node, { render }, options) => toNode('a', {
|
||||
href: renderUrl(node, render, options),
|
||||
}, node.content),
|
||||
img: (node, { render }) => toNode('img', {
|
||||
src: render(node.content),
|
||||
}, null),
|
||||
quote: (node) => toNode('blockquote', {}, [toNode('p', {}, node.content)]),
|
||||
code: (node) => toNode('pre', {}, node.content),
|
||||
style: (node) => toNode('span', toStyle(getStyleFromAttrs(node.attrs)), node.content),
|
||||
list: (node) => {
|
||||
const type = getUniqAttr(node.attrs);
|
||||
|
||||
return toNode(type ? 'ol' : 'ul', type ? { type } : {}, asListItems(node.content));
|
||||
},
|
||||
color: (node) => toNode('span', toStyle(`color: ${getUniqAttr(node.attrs)};`), node.content),
|
||||
};
|
||||
@@ -0,0 +1,146 @@
|
||||
/* eslint-disable no-plusplus,no-lonely-if */
|
||||
import {
|
||||
getUniqAttr,
|
||||
isStringNode,
|
||||
isTagNode,
|
||||
TagNode,
|
||||
TagNodeTree,
|
||||
} from "@bbob/plugin-helper";
|
||||
import type { NodeContent, TagNodeObject } from "@bbob/plugin-helper";
|
||||
import type { PresetTagsDefinition } from "@bbob/preset";
|
||||
import type { BbobPluginOptions } from "@bbob/core";
|
||||
|
||||
const isStartsWith = (node: string, type: string) => node[0] === type;
|
||||
|
||||
const getStyleFromAttrs = (attrs: Record<string, unknown>) => {
|
||||
return Object.keys(attrs)
|
||||
.reduce<string[]>((acc, key: "color" | "size") => {
|
||||
const value = attrs[key];
|
||||
|
||||
if (typeof value === "string") {
|
||||
if (key === "color") {
|
||||
return acc.concat(`color:${value};`);
|
||||
}
|
||||
|
||||
if (key === "size") {
|
||||
return acc.concat(`font-size:${value};`);
|
||||
}
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, [])
|
||||
.join(" ");
|
||||
};
|
||||
|
||||
const asListItems = (content: TagNodeTree): NodeContent[] => {
|
||||
let listIdx = 0;
|
||||
const listItems = [] as Array<NodeContent>;
|
||||
|
||||
const createItemNode = () => TagNode.create("li");
|
||||
const ensureListItem = (val: NodeContent) => {
|
||||
listItems[listIdx] = listItems[listIdx] || val;
|
||||
};
|
||||
const addItem = (val: NodeContent) => {
|
||||
const listItem = listItems[listIdx];
|
||||
|
||||
if (listItem && isTagNode(listItem) && Array.isArray(listItem.content)) {
|
||||
listItem.content = listItem.content.concat(val);
|
||||
}
|
||||
// else if (Array.isArray(listItem) && Array.isArray(listItems[listIdx])) {
|
||||
// listItems[listIdx] = listItems[listIdx].concat(val);
|
||||
// }
|
||||
};
|
||||
|
||||
if (Array.isArray(content)) {
|
||||
content.forEach((el) => {
|
||||
if (isStringNode(el) && isStartsWith(String(el), "*")) {
|
||||
if (listItems[listIdx]) {
|
||||
listIdx++;
|
||||
}
|
||||
ensureListItem(createItemNode());
|
||||
addItem(String(el).substr(1));
|
||||
} else if (isTagNode(el) && TagNode.isOf(el, "*")) {
|
||||
if (listItems[listIdx]) {
|
||||
listIdx++;
|
||||
}
|
||||
ensureListItem(createItemNode());
|
||||
} else if (!isTagNode(listItems[listIdx])) {
|
||||
listIdx++;
|
||||
ensureListItem(el);
|
||||
} else if (listItems[listIdx]) {
|
||||
addItem(el);
|
||||
} else {
|
||||
ensureListItem(el);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return listItems;
|
||||
};
|
||||
|
||||
const renderUrl = (node: TagNodeObject, render: BbobPluginOptions["render"]) =>
|
||||
getUniqAttr(node.attrs)
|
||||
? getUniqAttr(node.attrs)
|
||||
: render(node.content || []);
|
||||
|
||||
const toNode = (
|
||||
tag: string,
|
||||
attrs: Record<string, unknown>,
|
||||
content: TagNodeTree
|
||||
) => TagNode.create(tag, attrs, content);
|
||||
|
||||
const toStyle = (style: string) => ({ style });
|
||||
|
||||
const defaultTags: PresetTagsDefinition<
|
||||
| "b"
|
||||
| "i"
|
||||
| "u"
|
||||
| "s"
|
||||
| "url"
|
||||
| "img"
|
||||
| "quote"
|
||||
| "code"
|
||||
| "style"
|
||||
| "list"
|
||||
| "color"
|
||||
> = {
|
||||
b: (node) => toNode("span", toStyle("font-weight: bold;"), node.content),
|
||||
i: (node) => toNode("span", toStyle("font-style: italic;"), node.content),
|
||||
u: (node) =>
|
||||
toNode("span", toStyle("text-decoration: underline;"), node.content),
|
||||
s: (node) =>
|
||||
toNode("span", toStyle("text-decoration: line-through;"), node.content),
|
||||
url: (node, { render }) =>
|
||||
toNode(
|
||||
"a",
|
||||
{
|
||||
href: renderUrl(node, render),
|
||||
},
|
||||
node.content
|
||||
),
|
||||
img: (node, { render }) =>
|
||||
toNode(
|
||||
"img",
|
||||
{
|
||||
src: render(node.content),
|
||||
},
|
||||
null
|
||||
),
|
||||
quote: (node) => toNode("blockquote", {}, [toNode("p", {}, node.content)]),
|
||||
code: (node) => toNode("pre", {}, node.content),
|
||||
style: (node) =>
|
||||
toNode("span", toStyle(getStyleFromAttrs(node.attrs)), node.content),
|
||||
list: (node) => {
|
||||
const type = getUniqAttr(node.attrs);
|
||||
|
||||
return toNode(
|
||||
type ? "ol" : "ul",
|
||||
type ? { type } : {},
|
||||
asListItems(node.content)
|
||||
);
|
||||
},
|
||||
color: (node) =>
|
||||
toNode("span", toStyle(`color: ${getUniqAttr(node.attrs)};`), node.content),
|
||||
};
|
||||
|
||||
export default defaultTags;
|
||||
@@ -1,5 +0,0 @@
|
||||
/* eslint-disable indent */
|
||||
import { createPreset } from '@bbob/preset';
|
||||
import defaultTags from './defaultTags';
|
||||
|
||||
export default createPreset(defaultTags);
|
||||
@@ -0,0 +1,6 @@
|
||||
/* eslint-disable indent */
|
||||
import { createPreset } from "@bbob/preset";
|
||||
import defaultTags from "./defaultTags";
|
||||
export type * from "@bbob/preset";
|
||||
|
||||
export default createPreset(defaultTags);
|
||||
+8
-2
@@ -1,7 +1,13 @@
|
||||
import html from '@bbob/html'
|
||||
import html, { render } from '@bbob/html'
|
||||
import core from '@bbob/core'
|
||||
|
||||
import preset from '../src'
|
||||
|
||||
const parse = input => html(input, preset());
|
||||
const parse = (input: string) => {
|
||||
const tree = core(preset()).process(input, { render })
|
||||
|
||||
return html(input, preset())
|
||||
};
|
||||
|
||||
describe('@bbob/preset-html5', () => {
|
||||
test('[b]bolded text[/b]', () => {
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"outDir": "./types"
|
||||
},
|
||||
"include": [
|
||||
"./src/**/*"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user