2
0
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:
Nikolay Kost
2024-04-23 21:11:14 +02:00
committed by GitHub
parent 05246b2aea
commit 8797f7f363
149 changed files with 6102 additions and 3670 deletions
+3
View File
@@ -2,3 +2,6 @@ coverage
dist
lib
es
types
test/*.d.ts
test/*.map
+1 -1
View File
@@ -1,4 +1,4 @@
package-lock.json
pnpm-lock.yaml
coverage
src
!dist
+27 -13
View File
@@ -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
View File
@@ -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;
-5
View File
@@ -1,5 +0,0 @@
/* eslint-disable indent */
import { createPreset } from '@bbob/preset';
import defaultTags from './defaultTags';
export default createPreset(defaultTags);
+6
View File
@@ -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);
@@ -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]', () => {
+10
View File
@@ -0,0 +1,10 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"baseUrl": ".",
"outDir": "./types"
},
"include": [
"./src/**/*"
]
}