mirror of
https://github.com/tenrok/BBob.git
synced 2026-06-11 18:02:26 +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 @@ dist
|
||||
es
|
||||
lib
|
||||
test
|
||||
types
|
||||
test/*.d.ts
|
||||
test/*.map
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -9,12 +9,11 @@
|
||||
"bbob"
|
||||
],
|
||||
"dependencies": {
|
||||
"@bbob/core": "workspace:*",
|
||||
"@bbob/html": "workspace:*",
|
||||
"@bbob/plugin-helper": "workspace:*"
|
||||
"@bbob/core": "*",
|
||||
"@bbob/html": "*",
|
||||
"@bbob/plugin-helper": "*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"prop-types": "> 15.0",
|
||||
"react": "> 15.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -22,13 +21,24 @@
|
||||
"@testing-library/jest-dom": "^5.16.4",
|
||||
"@testing-library/react": "13.x",
|
||||
"react": "18.x",
|
||||
"react-dom": "18.x"
|
||||
"react-dom": "18.x",
|
||||
"@types/react": "18.x"
|
||||
},
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
"jsnext:main": "es/index.js",
|
||||
"browser": "dist/index.js",
|
||||
"browserName": "BbobReact",
|
||||
"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",
|
||||
@@ -40,19 +50,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": "8 KB"
|
||||
}
|
||||
],
|
||||
"bundlesize": [
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { render } from './render';
|
||||
|
||||
const content = (children, plugins, options) => React.Children.map(children, (child) => (typeof child === 'string' ? render(child, plugins, options) : child));
|
||||
|
||||
const Component = ({
|
||||
container,
|
||||
componentProps,
|
||||
children,
|
||||
plugins,
|
||||
options,
|
||||
}) => React.createElement(
|
||||
container,
|
||||
componentProps,
|
||||
content(children, plugins, options),
|
||||
);
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
Component.propTypes = {
|
||||
container: PropTypes.oneOfType([
|
||||
PropTypes.node,
|
||||
PropTypes.element,
|
||||
PropTypes.elementType,
|
||||
]),
|
||||
children: PropTypes.node.isRequired,
|
||||
plugins: PropTypes.arrayOf(PropTypes.func),
|
||||
componentProps: PropTypes.shape({
|
||||
className: PropTypes.string,
|
||||
}),
|
||||
options: PropTypes.shape({
|
||||
parser: PropTypes.func,
|
||||
skipParse: PropTypes.bool,
|
||||
onlyAllowTags: PropTypes.arrayOf(PropTypes.string),
|
||||
openTag: PropTypes.string,
|
||||
closeTag: PropTypes.string,
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
Component.defaultProps = {
|
||||
container: 'span',
|
||||
plugins: [],
|
||||
options: {},
|
||||
componentProps: {},
|
||||
};
|
||||
|
||||
export default Component;
|
||||
@@ -0,0 +1,34 @@
|
||||
import React, { ReactNode } from 'react';
|
||||
import type { BBobPlugins, BBobCoreOptions } from '@bbob/core';
|
||||
import { render } from './render';
|
||||
|
||||
const content = (children: ReactNode, plugins?: BBobPlugins, options?: BBobCoreOptions) => React.Children.map(children, (child) => (typeof child === 'string' ? render(child, plugins, options) : child));
|
||||
|
||||
export type BBobReactComponentProps = {
|
||||
children: ReactNode
|
||||
container: string
|
||||
componentProps: Record<string, unknown>
|
||||
plugins?: BBobPlugins
|
||||
options?: BBobCoreOptions
|
||||
}
|
||||
|
||||
const Component = ({
|
||||
container = 'span',
|
||||
componentProps = {},
|
||||
children,
|
||||
plugins = [],
|
||||
options = {},
|
||||
}: BBobReactComponentProps) => React.createElement(
|
||||
container,
|
||||
componentProps,
|
||||
content(children, plugins, options),
|
||||
);
|
||||
|
||||
Component.defaultProps = {
|
||||
container: 'span',
|
||||
plugins: [],
|
||||
options: {},
|
||||
componentProps: {},
|
||||
};
|
||||
|
||||
export default Component;
|
||||
@@ -1,57 +0,0 @@
|
||||
/* eslint-disable no-use-before-define */
|
||||
import React from 'react';
|
||||
import core from '@bbob/core';
|
||||
import * as html from '@bbob/html';
|
||||
|
||||
import { isTagNode, isEOL } from '@bbob/plugin-helper';
|
||||
|
||||
const toAST = (source, plugins, options) => core(plugins)
|
||||
.process(source, {
|
||||
...options,
|
||||
render: (input) => html.render(input, { stripTags: true }),
|
||||
}).tree;
|
||||
|
||||
const isContentEmpty = (content) => (!content || content.length === 0);
|
||||
|
||||
function tagToReactElement(node, index) {
|
||||
return React.createElement(
|
||||
node.tag,
|
||||
{ ...node.attrs, key: index },
|
||||
isContentEmpty(node.content) ? null : renderToReactNodes(node.content),
|
||||
);
|
||||
}
|
||||
|
||||
function renderToReactNodes(nodes) {
|
||||
const els = [].concat(nodes).reduce((arr, node, index) => {
|
||||
if (isTagNode(node)) {
|
||||
arr.push(tagToReactElement(node, index));
|
||||
return arr;
|
||||
}
|
||||
|
||||
if (isEOL(node)) {
|
||||
arr.push(node);
|
||||
return arr;
|
||||
}
|
||||
|
||||
const lastIdx = arr.length - 1;
|
||||
const prevNode = lastIdx >= 0 ? arr[lastIdx] : null;
|
||||
|
||||
if (prevNode !== null && !isTagNode(prevNode) && !isEOL(prevNode)) {
|
||||
const prevArr = arr; // stupid eslint
|
||||
prevArr[lastIdx] += node;
|
||||
return prevArr;
|
||||
}
|
||||
|
||||
arr.push(node);
|
||||
|
||||
return arr;
|
||||
}, []);
|
||||
return els;
|
||||
}
|
||||
|
||||
function render(source, plugins, options) {
|
||||
return renderToReactNodes(toAST(source, plugins, options));
|
||||
}
|
||||
|
||||
export { render };
|
||||
export default render;
|
||||
@@ -0,0 +1,90 @@
|
||||
/* eslint-disable no-use-before-define */
|
||||
import React, { ReactNode } from "react";
|
||||
import { render as htmlrender } from "@bbob/html";
|
||||
import core, {
|
||||
BBobCoreOptions,
|
||||
BBobCoreTagNodeTree,
|
||||
BBobPlugins,
|
||||
} from "@bbob/core";
|
||||
|
||||
import {
|
||||
isTagNode,
|
||||
isStringNode,
|
||||
isEOL,
|
||||
TagNode,
|
||||
TagNodeTree,
|
||||
} from "@bbob/plugin-helper";
|
||||
|
||||
const toAST = (
|
||||
source: string,
|
||||
plugins?: BBobPlugins,
|
||||
options?: BBobCoreOptions
|
||||
) =>
|
||||
core(plugins).process(source, {
|
||||
...options,
|
||||
render: (input) => htmlrender(input, { stripTags: true }),
|
||||
}).tree;
|
||||
|
||||
const isContentEmpty = (content: TagNodeTree) => {
|
||||
if (!content) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (typeof content === "number") {
|
||||
return String(content).length === 0;
|
||||
}
|
||||
|
||||
return Array.isArray(content) ? content.length === 0 : !content;
|
||||
};
|
||||
|
||||
function tagToReactElement(node: TagNode, index: number) {
|
||||
return React.createElement(
|
||||
node.tag,
|
||||
{ ...node.attrs, key: index },
|
||||
isContentEmpty(node.content) ? null : renderToReactNodes(node.content)
|
||||
);
|
||||
}
|
||||
|
||||
function renderToReactNodes(nodes: BBobCoreTagNodeTree | TagNodeTree) {
|
||||
if (Array.isArray(nodes) && nodes.length) {
|
||||
return nodes.reduce<ReactNode[]>((arr, node, index) => {
|
||||
if (isTagNode(node)) {
|
||||
arr.push(tagToReactElement(node, index));
|
||||
return arr;
|
||||
}
|
||||
|
||||
if (isStringNode(node)) {
|
||||
if (isEOL(String(node))) {
|
||||
arr.push(node);
|
||||
return arr;
|
||||
}
|
||||
|
||||
const lastIdx = arr.length - 1;
|
||||
const prevArr = arr; // stupid eslint
|
||||
const prevNode = lastIdx >= 0 ? prevArr[lastIdx] : null;
|
||||
|
||||
if (prevArr[lastIdx] && prevNode !== null && !isEOL(String(prevNode))) {
|
||||
prevArr[lastIdx] += String(node);
|
||||
|
||||
return prevArr;
|
||||
}
|
||||
|
||||
arr.push(node);
|
||||
}
|
||||
|
||||
return arr;
|
||||
}, []);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
function render(
|
||||
source: string,
|
||||
plugins?: BBobPlugins,
|
||||
options?: BBobCoreOptions
|
||||
) {
|
||||
return renderToReactNodes(toAST(source, plugins, options));
|
||||
}
|
||||
|
||||
export { render };
|
||||
export default render;
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"outDir": "./types"
|
||||
},
|
||||
"include": [
|
||||
"./src/**/*"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user