From 4c365c61df1115bcbf9c5350515592591004710f Mon Sep 17 00:00:00 2001 From: Troy Alford Date: Tue, 29 Oct 2024 16:48:46 -0700 Subject: [PATCH 1/2] add a proper bun dependency on TroyAlford/basis --- bun.lockb | Bin 130200 -> 135736 bytes package.json | 4 +- yarn.lock | 125 ++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 121 insertions(+), 8 deletions(-) diff --git a/bun.lockb b/bun.lockb index 3a6aadb454ee8f0884108f40cd032c0540667df0..cb4c543ed15621256feb8d7dd9e768fdd6851ef1 100755 GIT binary patch delta 17212 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 bW-V$g)GP2`V2CZZSx1vITl{sKz5RaxrpF82 delta 14601 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 F{(lz@-Z%gN diff --git a/package.json b/package.json index 7e198ac..ccc4224 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "@types/bun": "^1.1.6", "@typescript-eslint/eslint-plugin": "^7.15.0", "@typescript-eslint/parser": "^7.15.0", - "basis": "TroyAlford/basis", + "basis": "github:TroyAlford/basis#v1.1.0", "concurrently": "^8.2.2", "cross-env": "^7.0.3", "eslint": "^8.57.0", @@ -55,7 +55,7 @@ "repository": "TroyAlford/react-jsx-parser", "scripts": { "build": "bun build:types && bun build:code", - "build:code": "bun build --target=browser --outfile=./dist/react-jsx-parser.min.js ./source/index.ts", + "build:code": "bun build --target=browser --outfile=./dist/react-jsx-parser.min.js ./source/index.ts --external react --external react-dom", "build:types": "bun run tsc -p ./tsconfig.json -d --emitDeclarationOnly", "develop": "NODE_ENV=production concurrently -n build,ts,demo -c green,cyan,yellow \"bun build:code --watch\" \"bun build:types --watch\" \"bun serve\"", "lint": "bun eslint --ext .js,.ts,.tsx source/", diff --git a/yarn.lock b/yarn.lock index e4a57e1..05d1074 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1,6 +1,6 @@ # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. # yarn lockfile v1 -# bun ./bun.lockb --hash: 033B634DA0583800-43756a934708d338-AB2E8226CA6E6215-f5a9da1d383ecd4e +# bun ./bun.lockb --hash: 1614930542A7AB39-1847a6ab6c9799dc-70F392D8ECD54409-1a4a46a39b28aca1 "@babel/runtime@^7.21.0": @@ -31,6 +31,11 @@ debug "^4.3.1" minimatch "^3.1.2" +"@eslint/core@^0.7.0": + version "0.7.0" + resolved "https://registry.npmjs.org/@eslint/core/-/core-0.7.0.tgz" + integrity sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw== + "@eslint/eslintrc@^2.1.4": version "2.1.4" resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz" @@ -71,6 +76,11 @@ resolved "https://registry.npmjs.org/@eslint/js/-/js-9.10.0.tgz" integrity sha512-fuXtbiP5GWIn8Fz+LWoOMVf/Jxm+aajZYkhi6CuEm4SxymFM+eUWzbO9qXT+L0iCkL5+KGYMCSGxo686H19S1g== +"@eslint/js@9.13.0": + version "9.13.0" + resolved "https://registry.npmjs.org/@eslint/js/-/js-9.13.0.tgz" + integrity sha512-IFLyoY4d72Z5y/6o/BazFBezupzI/taV8sGumxTAVw3lXG9A6md1Dc34T9s1FoD/an9pJH8RHbAxsaEbBed9lA== + "@eslint/object-schema@^2.1.4": version "2.1.4" resolved "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz" @@ -83,6 +93,13 @@ dependencies: levn "^0.4.1" +"@eslint/plugin-kit@^0.2.0": + version "0.2.2" + resolved "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.2.tgz" + integrity sha512-CXtq5nR4Su+2I47WPOlWud98Y5Lv8Kyxp2ukhgFx/eW6Blm18VXJO5WuQylPugRo8nbluoi6GvvxBLqHcvqUUw== + dependencies: + levn "^0.4.1" + "@happy-dom/global-registrator@^14.12.3": version "14.12.3" resolved "https://registry.npmjs.org/@happy-dom/global-registrator/-/global-registrator-14.12.3.tgz" @@ -90,6 +107,19 @@ dependencies: happy-dom "^14.12.3" +"@humanfs/core@^0.19.1": + version "0.19.1" + resolved "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz" + integrity sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA== + +"@humanfs/node@^0.16.5": + version "0.16.6" + resolved "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz" + integrity sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw== + dependencies: + "@humanwhocodes/retry" "^0.3.0" + "@humanfs/core" "^0.19.1" + "@humanwhocodes/config-array@^0.11.14": version "0.11.14" resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz" @@ -114,6 +144,11 @@ resolved "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz" integrity sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew== +"@humanwhocodes/retry@^0.3.0", "@humanwhocodes/retry@^0.3.1": + version "0.3.1" + resolved "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz" + integrity sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA== + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" @@ -159,6 +194,16 @@ resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz" integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== +"@types/estree@^1.0.6": + version "1.0.6" + resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz" + integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== + +"@types/json-schema@^7.0.15": + version "7.0.15" + resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== + "@types/json5@^0.0.29": version "0.0.29" resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" @@ -289,6 +334,11 @@ resolved "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz" integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== +acorn@^8.14.0: + version "8.14.0" + resolved "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz" + integrity sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA== + acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" @@ -449,11 +499,11 @@ balanced-match@^1.0.0: resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -"basis@TroyAlford/basis": - version "github:TroyAlford/basis#5c364bd" - resolved "github:TroyAlford/basis#5c364bd" +"basis@github:TroyAlford/basis#v1.1.0": + version "github:TroyAlford/basis#b682bef" + resolved "github:TroyAlford/basis#b682bef" dependencies: - eslint "^9.9.0" + eslint "^9.12.0" brace-expansion@^1.1.7: version "1.1.11" @@ -897,7 +947,7 @@ escape-string-regexp@^4.0.0: "@humanwhocodes/module-importer" "^1.0.1" json-stable-stringify-without-jsonify "^1.0.1" -"eslint@^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7", eslint@^9.9.0: +"eslint@^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7": version "9.10.0" resolved "https://registry.npmjs.org/eslint/-/eslint-9.10.0.tgz" integrity sha512-Y4D0IgtBZfOcOUAIQTSXBKoNGfY0REGqHJG6+Q81vNippW5YlKjHFj4soMxamKK1NXHUWuBZTLdU3Km+L/pcHw== @@ -937,6 +987,47 @@ escape-string-regexp@^4.0.0: strip-ansi "^6.0.1" text-table "^0.2.0" +eslint@^9.12.0: + version "9.13.0" + resolved "https://registry.npmjs.org/eslint/-/eslint-9.13.0.tgz" + integrity sha512-EYZK6SX6zjFHST/HRytOdA/zE72Cq/bfw45LSyuwrdvcclb/gqV8RRQxywOBEWO2+WDpva6UZa4CcDeJKzUCFA== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.11.0" + "@eslint/config-array" "^0.18.0" + "@eslint/core" "^0.7.0" + "@eslint/eslintrc" "^3.1.0" + "@eslint/js" "9.13.0" + "@eslint/plugin-kit" "^0.2.0" + "@humanfs/node" "^0.16.5" + "@humanwhocodes/module-importer" "^1.0.1" + "@humanwhocodes/retry" "^0.3.1" + "@types/estree" "^1.0.6" + "@types/json-schema" "^7.0.15" + ajv "^6.12.4" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + escape-string-regexp "^4.0.0" + eslint-scope "^8.1.0" + eslint-visitor-keys "^4.1.0" + espree "^10.2.0" + esquery "^1.5.0" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^8.0.0" + find-up "^5.0.0" + glob-parent "^6.0.2" + ignore "^5.2.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + json-stable-stringify-without-jsonify "^1.0.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.3" + text-table "^0.2.0" + eslint-config-airbnb@^19.0.4: version "19.0.4" resolved "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-19.0.4.tgz" @@ -1063,6 +1154,14 @@ eslint-scope@^8.0.2: esrecurse "^4.3.0" estraverse "^5.2.0" +eslint-scope@^8.1.0: + version "8.2.0" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz" + integrity sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: version "3.4.3" resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz" @@ -1073,6 +1172,11 @@ eslint-visitor-keys@^4.0.0: resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz" integrity sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw== +eslint-visitor-keys@^4.1.0, eslint-visitor-keys@^4.2.0: + version "4.2.0" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz" + integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw== + espree@^9.6.0, espree@^9.6.1: version "9.6.1" resolved "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz" @@ -1091,6 +1195,15 @@ espree@^10.0.1, espree@^10.1.0: acorn-jsx "^5.3.2" eslint-visitor-keys "^4.0.0" +espree@^10.2.0: + version "10.3.0" + resolved "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz" + integrity sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg== + dependencies: + acorn "^8.14.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^4.2.0" + esquery@^1.4.2, esquery@^1.5.0: version "1.6.0" resolved "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz" From 76960f82f4c6e6da99c50a391e989db7df50a9da Mon Sep 17 00:00:00 2001 From: Troy Alford Date: Tue, 29 Oct 2024 16:49:10 -0700 Subject: [PATCH 2/2] add better types for Component prop, and add JSDoc to all props/methods --- source/components/JsxParser.tsx | 93 ++++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 2 deletions(-) diff --git a/source/components/JsxParser.tsx b/source/components/JsxParser.tsx index 2344986..57d2e15 100644 --- a/source/components/JsxParser.tsx +++ b/source/components/JsxParser.tsx @@ -1,6 +1,6 @@ import * as Acorn from 'acorn' import * as AcornJSX from 'acorn-jsx' -import React, { ComponentType, ExoticComponent, Fragment } from 'react' +import React, { Fragment } from 'react' import ATTRIBUTES from '../constants/attributeNames' import { canHaveChildren, canHaveWhitespace } from '../constants/specialTags' import { NullishShortCircuit } from '../errors/NullishShortCircuit' @@ -14,24 +14,74 @@ function handleNaN(child: T): T | 'NaN' { type ParsedJSX = React.ReactNode | boolean | string type ParsedTree = ParsedJSX | ParsedJSX[] | null + +/** + * Props for the JsxParser component + */ export type TProps = { + /** Whether to allow rendering of unrecognized HTML elements. Defaults to true. */ allowUnknownElements?: boolean, + + /** + * Whether to auto-close void elements like ,
,
etc. in HTML style. + * Defaults to false. + */ autoCloseVoidElements?: boolean, + + /** Object containing values that can be referenced in the JSX string */ bindings?: { [key: string]: unknown; }, + + /** + * Array of attribute names or RegExp patterns to blacklist. + * By default removes 'on*' attributes + */ blacklistedAttrs?: Array, + + /** + * Array of HTML tag names to blacklist. + * By default removes 'script' tags + */ blacklistedTags?: string[], + + /** CSS class name(s) to add to the wrapper div */ className?: string, - components?: Record, + + /** Map of component names to their React component definitions */ + components?: Record< + string, + | React.ComponentType // allows for class components + | React.ExoticComponent // allows for forwardRef + | (() => React.ReactNode) // allows for function components + >, + + /** If true, only renders custom components defined in the components prop */ componentsOnly?: boolean, + + /** If true, disables usage of React.Fragment. May affect whitespace handling */ disableFragments?: boolean, + + /** If true, disables automatic generation of key props */ disableKeyGeneration?: boolean, + + /** The JSX string to parse and render */ jsx?: string, + + /** Callback function when parsing/rendering errors occur */ onError?: (error: Error) => void, + + /** If true, shows parsing/rendering warnings in console */ showWarnings?: boolean, + + /** Custom error renderer function */ renderError?: (props: { error: string }) => React.ReactNode | null, + + /** Whether to wrap output in a div. If false, renders children directly */ renderInWrapper?: boolean, + + /** Custom renderer for unrecognized elements */ renderUnrecognized?: (tagName: string) => React.ReactNode | null, } + type Scope = Record export default class JsxParser extends React.Component { @@ -55,8 +105,14 @@ export default class JsxParser extends React.Component { renderUnrecognized: () => null, } + /** Stores the parsed React elements */ private ParsedChildren: ParsedTree = null + /** + * Parses a JSX string into React elements + * @param jsx - The JSX string to parse + * @returns The parsed React node(s) or null if parsing fails + */ #parseJSX = (jsx: string): React.ReactNode | React.ReactNode[] | null => { const parser = Acorn.Parser.extend(AcornJSX.default({ autoCloseVoidElements: this.props.autoCloseVoidElements, @@ -80,6 +136,12 @@ export default class JsxParser extends React.Component { return parsed.map(p => this.#parseExpression(p)).filter(Boolean) } + /** + * Parses a single JSX expression into its corresponding value/element + * @param expression - The JSX expression to parse + * @param scope - Optional scope for variable resolution + * @returns The parsed value/element + */ #parseExpression = (expression: AcornJSX.Expression, scope?: Scope): any => { switch (expression.type) { case 'JSXAttribute': @@ -204,6 +266,12 @@ export default class JsxParser extends React.Component { } } + /** + * Parses a chain expression (optional chaining) + * @param expression - The chain expression to parse + * @param scope - Optional scope for variable resolution + * @returns The parsed value + */ #parseChainExpression = (expression: AcornJSX.ChainExpression, scope?: Scope): any => { try { return this.#parseExpression(expression.expression, scope) @@ -213,6 +281,12 @@ export default class JsxParser extends React.Component { } } + /** + * Parses a member expression (e.g., obj.prop or obj['prop']) + * @param expression - The member expression to parse + * @param scope - Optional scope for variable resolution + * @returns The resolved member value + */ #parseMemberExpression = (expression: AcornJSX.MemberExpression, scope?: Scope): any => { const object = this.#parseExpression(expression.object, scope) @@ -242,11 +316,22 @@ export default class JsxParser extends React.Component { return member } + /** + * Parses a JSX element name (simple or member expression) + * @param element - The JSX identifier or member expression + * @returns The parsed element name as a string + */ #parseName = (element: AcornJSX.JSXIdentifier | AcornJSX.JSXMemberExpression): string => { if (element.type === 'JSXIdentifier') { return element.name } return `${this.#parseName(element.object)}.${this.#parseName(element.property)}` } + /** + * Parses a JSX element into React elements + * @param element - The JSX element to parse + * @param scope - Optional scope for variable resolution + * @returns The parsed React node(s) or null + */ #parseElement = ( element: AcornJSX.JSXElement | AcornJSX.JSXFragment, scope?: Scope, @@ -357,6 +442,10 @@ export default class JsxParser extends React.Component { return React.createElement(component || lowerName, props, children) } + /** + * Renders the parsed JSX content + * @returns The rendered React elements wrapped in a div (if renderInWrapper is true) + */ render() { const jsx = (this.props.jsx || '').trim().replace(/]*)>/g, '') this.ParsedChildren = this.#parseJSX(jsx)