Initial commit: Developer Tools MVP with visual editor

- Complete React app with 7 developer tools
- JSON Tool with visual structured editor
- Serialize Tool with visual structured editor
- URL, Base64, CSV/JSON, Beautifier, Diff tools
- Responsive navigation with dropdown menu
- Dark/light mode toggle
- Mobile-responsive design with sticky header
- All tools working with copy/paste functionality
This commit is contained in:
dwindown
2025-08-02 09:31:26 +07:00
commit 7f2dd5260f
45657 changed files with 4730486 additions and 0 deletions

15
node_modules/jsx-ast-utils/src/values/JSXElement.js generated vendored Normal file
View File

@@ -0,0 +1,15 @@
/**
* Extractor function for a JSXElement type value node.
*
* Returns self-closing element with correct name.
*/
export default function extractValueFromJSXElement(value) {
// eslint-disable-next-line global-require
const getValue = require('.').default;
const Tag = value.openingElement.name.name;
if (value.openingElement.selfClosing) {
return `<${Tag} />`;
}
return `<${Tag}>${[].concat(value.children).map((x) => getValue(x)).join('')}</${Tag}>`;
}

14
node_modules/jsx-ast-utils/src/values/JSXFragment.js generated vendored Normal file
View File

@@ -0,0 +1,14 @@
/**
* Extractor function for a JSXFragment type value node.
*
* Returns self-closing element with correct name.
*/
export default function extractValueFromJSXFragment(value) {
// eslint-disable-next-line global-require
const getValue = require('.').default;
if (value.children.length === 0) {
return '<></>';
}
return `<>${[].concat(value.children).map((x) => getValue(x)).join('')}</>`;
}

8
node_modules/jsx-ast-utils/src/values/JSXText.js generated vendored Normal file
View File

@@ -0,0 +1,8 @@
/**
* Extractor function for a JSXText type value node.
*
* Returns self-closing element with correct name.
*/
export default function extractValueFromJSXText(value) {
return value.raw;
}

20
node_modules/jsx-ast-utils/src/values/Literal.js generated vendored Normal file
View File

@@ -0,0 +1,20 @@
/**
* Extractor function for a Literal type value node.
*
* @param - value - AST Value object with type `Literal`
* @returns { String|Boolean } - The extracted value converted to correct type.
*/
export default function extractValueFromLiteral(value) {
const { value: extractedValue } = value;
const normalizedStringValue = typeof extractedValue === 'string' && extractedValue.toLowerCase();
if (normalizedStringValue === 'true') {
return true;
}
if (normalizedStringValue === 'false') {
return false;
}
return extractedValue;
}

View File

@@ -0,0 +1,14 @@
/**
* Extractor function for an ArrayExpression type value node.
* An array expression is an expression with [] syntax.
*
* @returns - An array of the extracted elements.
*/
export default function extractValueFromArrayExpression(value) {
// eslint-disable-next-line global-require
const getValue = require('.').default;
return value.elements.map((element) => {
if (element === null) return undefined;
return getValue(element);
});
}

View File

@@ -0,0 +1,13 @@
/**
* Extractor function for a AssignmentExpression type value node.
* An assignment expression looks like `x = y` or `x += y` in expression position.
* This will return the assignment as the value.
*
* @param - value - AST Value object with type `AssignmentExpression`
* @returns - The extracted value converted to correct type.
*/
export default function extractValueFromAssignmentExpression(value) {
// eslint-disable-next-line global-require
const getValue = require('.').default;
return `${getValue(value.left)} ${value.operator} ${getValue(value.right)}`;
}

View File

@@ -0,0 +1,69 @@
/**
* Extractor function for a BinaryExpression type value node.
* A binary expression has a left and right side separated by an operator
* such as `a + b`.
*
* @param - value - AST Value object with type `BinaryExpression`
* @returns - The extracted value converted to correct type.
*/
export default function extractValueFromBinaryExpression(value) {
// eslint-disable-next-line global-require
const getValue = require('.').default;
const { operator, left, right } = value;
const leftVal = getValue(left);
const rightVal = getValue(right);
switch (operator) {
case '==':
return leftVal == rightVal; // eslint-disable-line
case '!=':
return leftVal != rightVal; // eslint-disable-line
case '===':
return leftVal === rightVal;
case '!==':
return leftVal !== rightVal;
case '<':
return leftVal < rightVal;
case '<=':
return leftVal <= rightVal;
case '>':
return leftVal > rightVal;
case '>=':
return leftVal >= rightVal;
case '<<':
return leftVal << rightVal; // eslint-disable-line no-bitwise
case '>>':
return leftVal >> rightVal; // eslint-disable-line no-bitwise
case '>>>':
return leftVal >>> rightVal; // eslint-disable-line no-bitwise
case '+':
return leftVal + rightVal;
case '-':
return leftVal - rightVal;
case '*':
return leftVal * rightVal;
case '/':
return leftVal / rightVal;
case '%':
return leftVal % rightVal;
case '|':
return leftVal | rightVal; // eslint-disable-line no-bitwise
case '^':
return leftVal ^ rightVal; // eslint-disable-line no-bitwise
case '&':
return leftVal & rightVal; // eslint-disable-line no-bitwise
case 'in':
try {
return leftVal in rightVal;
} catch (err) {
return false;
}
case 'instanceof':
if (typeof rightVal !== 'function') {
return false;
}
return leftVal instanceof rightVal;
default:
return undefined;
}
}

View File

@@ -0,0 +1,24 @@
/**
* Extractor function for a BindExpression type value node.
* A bind expression looks like `::this.foo`
* This will return `this.foo.bind(this)` as the value to indicate its existence,
* since we can not execute the function this.foo.bind(this) in a static environment.
*
* @param - value - AST Value object with type `BindExpression`
* @returns - The extracted value converted to correct type.
*/
export default function extractValueFromBindExpression(value) {
// eslint-disable-next-line global-require
const getValue = require('.').default;
const callee = getValue(value.callee);
// If value.object === null, the callee must be a MemberExpression.
// https://github.com/babel/babylon/blob/master/ast/spec.md#bindexpression
const object = value.object === null ? getValue(value.callee.object) : getValue(value.object);
if (value.object && value.object.property) {
return `${object}.${callee}.bind(${object})`;
}
return `${callee}.bind(${object})`;
}

View File

@@ -0,0 +1,15 @@
/**
* Extractor function for a CallExpression type value node.
* A call expression looks like `bar()`
* This will return `bar` as the value to indicate its existence,
* since we can not execute the function bar in a static environment.
*
* @param - value - AST Value object with type `CallExpression`
* @returns - The extracted value converted to correct type.
*/
export default function extractValueFromCallExpression(value) {
// eslint-disable-next-line global-require
const getValue = require('.').default;
const args = Array.isArray(value.arguments) ? value.arguments.map((x) => getValue(x)).join(', ') : '';
return `${getValue(value.callee)}${value.optional ? '?.' : ''}(${args})`;
}

View File

@@ -0,0 +1,13 @@
/**
* Extractor function for a ChainExpression type value node.
* A member expression is accessing a property on an object `obj.property`.
*
* @param - value - AST Value object with type `ChainExpression`
* @returns - The extracted value converted to correct type
* and maintaing `obj?.property` convention.
*/
export default function extractValueFromChainExpression(value) {
// eslint-disable-next-line global-require
const getValue = require('.').default;
return getValue(value.expression || value);
}

View File

@@ -0,0 +1,17 @@
/**
* Extractor function for a ConditionalExpression type value node.
*
* @param - value - AST Value object with type `ConditionalExpression`
* @returns - The extracted value converted to correct type.
*/
export default function extractValueFromConditionalExpression(value) {
// eslint-disable-next-line global-require
const getValue = require('.').default;
const {
test,
alternate,
consequent,
} = value;
return getValue(test) ? getValue(consequent) : getValue(alternate);
}

View File

@@ -0,0 +1,11 @@
/**
* Extractor function for a FunctionExpression type value node.
* Statically, we can't execute the given function, so just return a function
* to indicate that the value is present.
*
* @param - value - AST Value object with type `FunctionExpression`
* @returns - The extracted value converted to correct type.
*/
export default function extractValueFromFunctionExpression(value) {
return () => value;
}

View File

@@ -0,0 +1,28 @@
const JS_RESERVED = {
Array,
Date,
Infinity,
Math,
Number,
Object,
String,
undefined,
};
/**
* Extractor function for a Identifier type value node.
* An Identifier is usually a reference to a variable.
* Just return variable name to determine its existence.
*
* @param - value - AST Value object with type `Identifier`
* @returns - The extracted value converted to correct type.
*/
export default function extractValueFromIdentifier(value) {
const { name } = value;
if (Object.hasOwnProperty.call(JS_RESERVED, name)) {
return JS_RESERVED[name];
}
return name;
}

View File

@@ -0,0 +1,24 @@
/**
* Extractor function for a LogicalExpression type value node.
* A logical expression is `a && b` or `a || b`, so we evaluate both sides
* and return the extracted value of the expression.
*
* @param - value - AST Value object with type `LogicalExpression`
* @returns - The extracted value converted to correct type.
*/
export default function extractValueFromLogicalExpression(value) {
// eslint-disable-next-line global-require
const getValue = require('.').default;
const { operator, left, right } = value;
const leftVal = getValue(left);
const rightVal = getValue(right);
if (operator === '&&') {
return leftVal && rightVal;
}
if (operator === '??') {
// return leftVal ?? rightVal; // TODO: update to babel 7
return (leftVal === null || typeof leftVal === 'undefined') ? rightVal : leftVal;
}
return leftVal || rightVal;
}

View File

@@ -0,0 +1,13 @@
/**
* Extractor function for a MemberExpression type value node.
* A member expression is accessing a property on an object `obj.property`.
*
* @param - value - AST Value object with type `MemberExpression`
* @returns - The extracted value converted to correct type
* and maintaing `obj.property` convention.
*/
export default function extractValueFromMemberExpression(value) {
// eslint-disable-next-line global-require
const getValue = require('.').default;
return `${getValue(value.object)}${value.optional ? '?.' : '.'}${getValue(value.property)}`;
}

View File

@@ -0,0 +1,9 @@
/**
* Extractor function for a NewExpression type value node.
* A new expression instantiates an object with `new` keyword.
*
* @returns - an empty object.
*/
export default function extractValueFromNewExpression() {
return new Object(); // eslint-disable-line
}

View File

@@ -0,0 +1,23 @@
import assign from 'object.assign';
/**
* Extractor function for an ObjectExpression type value node.
* An object expression is using {}.
*
* @returns - a representation of the object
*/
export default function extractValueFromObjectExpression(value) {
// eslint-disable-next-line global-require
const getValue = require('.').default;
return value.properties.reduce((obj, property) => {
// Support types: SpreadProperty and ExperimentalSpreadProperty
if (/^(?:Experimental)?Spread(?:Property|Element)$/.test(property.type)) {
if (property.argument.type === 'ObjectExpression') {
return assign({}, obj, extractValueFromObjectExpression(property.argument));
}
} else {
return assign({}, obj, { [getValue(property.key)]: getValue(property.value) });
}
return obj;
}, {});
}

View File

@@ -0,0 +1,13 @@
/**
* Extractor function for a OptionalCallExpression type value node.
* A member expression is accessing a property on an object `obj.property` and invoking it.
*
* @param - value - AST Value object with type `OptionalCallExpression`
* @returns - The extracted value converted to correct type
* and maintaing `obj.property?.()` convention.
*/
export default function extractValueFromOptionalCallExpression(value) {
// eslint-disable-next-line global-require
const getValue = require('.').default;
return `${getValue(value.callee)}?.(${value.arguments.map((x) => getValue(x)).join(', ')})`;
}

View File

@@ -0,0 +1,13 @@
/**
* Extractor function for a OptionalMemberExpression type value node.
* A member expression is accessing a property on an object `obj.property`.
*
* @param - value - AST Value object with type `OptionalMemberExpression`
* @returns - The extracted value converted to correct type
* and maintaing `obj?.property` convention.
*/
export default function extractValueFromOptionalMemberExpression(value) {
// eslint-disable-next-line global-require
const getValue = require('.').default;
return `${getValue(value.object)}?.${getValue(value.property)}`;
}

View File

@@ -0,0 +1,13 @@
/**
* Extractor function for a SequenceExpression type value node.
* A Sequence expression is an object with an attribute named
* expressions which contains an array of different types
* of expression objects.
*
* @returns - An array of the extracted elements.
*/
export default function extractValueFromSequenceExpression(value) {
// eslint-disable-next-line global-require
const getValue = require('.').default;
return value.expressions.map((element) => getValue(element));
}

View File

@@ -0,0 +1,11 @@
/**
* Extractor function for a SpreadElement type value node.
* We can't statically evaluate an array spread, so just return
* undefined.
*
* @param - value - AST Value object with type `SpreadElement`
* @returns - An prototypeless object.
*/
export default function extractValueFromSpreadElement() {
return undefined;
}

View File

@@ -0,0 +1,97 @@
const extractValueFromThisExpression = require('./ThisExpression').default;
const extractValueFromCallExpression = require('./CallExpression').default;
function navigate(obj, prop, value) {
if (value.computed) {
return value.optional ? `${obj}?.[${prop}]` : `${obj}[${prop}]`;
}
return value.optional ? `${obj}?.${prop}` : `${obj}.${prop}`;
}
/**
* Extractor function for a TSNonNullExpression type value node.
* A TSNonNullExpression is accessing a TypeScript Non-Null Assertion
* Operator !
*
* @param - value - AST Value object with type `TSNonNullExpression`
* @returns - The extracted value converted to correct type
* and maintaing `obj.property` convention.
*/
export default function extractValueFromTSNonNullExpression(value) {
// eslint-disable-next-line global-require
// const getValue = require('.').default;
const errorMessage = 'The prop value with an expression type of TSNonNullExpression could not be resolved. Please file an issue ( https://github.com/jsx-eslint/jsx-ast-utils/issues/new ) to get this fixed immediately.';
// it's just the name
if (value.type === 'Identifier') {
const { name } = value;
return name;
}
if (value.type === 'Literal') {
return value.value;
}
if (value.type === 'TSAsExpression') {
return extractValueFromTSNonNullExpression(value.expression);
}
if (value.type === 'CallExpression') {
return extractValueFromCallExpression(value);
}
if (value.type === 'ThisExpression') {
return extractValueFromThisExpression();
}
// does not contains properties & is not parenthesized
if (value.type === 'TSNonNullExpression' && (!value.extra || value.extra.parenthesized === false)) {
const { expression } = value;
return `${extractValueFromTSNonNullExpression(expression)}${'!'}`;
}
// does not contains properties & is parenthesized
if (value.type === 'TSNonNullExpression' && value.extra && value.extra.parenthesized === true) {
const { expression } = value;
return `${'('}${extractValueFromTSNonNullExpression(expression)}${'!'}${')'}`;
}
if (value.type === 'MemberExpression') {
// contains a property & is not parenthesized
if ((!value.extra || value.extra.parenthesized === false)) {
return navigate(
extractValueFromTSNonNullExpression(value.object),
extractValueFromTSNonNullExpression(value.property),
value,
);
}
// contains a property & is parenthesized
if (value.extra && value.extra.parenthesized === true) {
const result = navigate(
extractValueFromTSNonNullExpression(value.object),
extractValueFromTSNonNullExpression(value.property),
value,
);
return `(${result})`;
}
}
// try to fail silently, if specs for TSNonNullExpression change
// not throw, only log error. Similar to how it was done previously
if (value.expression) {
let { expression } = value;
while (expression) {
if (expression.type === 'Identifier') {
// eslint-disable-next-line no-console
console.error(errorMessage);
return expression.name;
}
({ expression } = expression);
}
}
// eslint-disable-next-line no-console
console.error(errorMessage);
return '';
}

View File

@@ -0,0 +1,9 @@
import extractValueFromTemplateLiteral from './TemplateLiteral';
/**
* Returns the string value of a tagged template literal object.
* Redirects the bulk of the work to `TemplateLiteral`.
*/
export default function extractValueFromTaggedTemplateExpression(value) {
return extractValueFromTemplateLiteral(value.quasi);
}

View File

@@ -0,0 +1,35 @@
function sortStarts(a, b) {
return (a.range ? a.range[0] : a.start) - (b.range ? b.range[0] : b.start);
}
/**
* Returns the string value of a template literal object.
* Tries to build it as best as it can based on the passed
* prop. For instance `This is a ${prop}` will return 'This is a {prop}'.
*
* If the template literal builds to undefined (`${undefined}`), then
* this should return "undefined".
*/
export default function extractValueFromTemplateLiteral(value) {
const {
quasis,
expressions,
} = value;
const partitions = quasis.concat(expressions);
return partitions.sort(sortStarts).map(({ type, value: { raw } = {}, name }) => {
if (type === 'TemplateElement') {
return raw;
}
if (type === 'Identifier') {
return name === 'undefined' ? name : `{${name}}`;
}
if (type.indexOf('Expression') > -1) {
return `{${type}}`;
}
return '';
}).join('');
}

View File

@@ -0,0 +1,9 @@
/**
* Extractor function for a ThisExpression type value node.
* A this expression is using `this` as an identifier.
*
* @returns - 'this' as a string.
*/
export default function extractValueFromThisExpression() {
return 'this';
}

View File

@@ -0,0 +1,13 @@
/**
* Extractor function for a TypeCastExpression type value node.
* A type cast expression looks like `(this.handleClick: (event: MouseEvent) => void))`
* This will return the expression `this.handleClick`.
*
* @param - value - AST Value object with type `TypeCastExpression`
* @returns - The extracted value converted to correct type.
*/
export default function extractValueFromTypeCastExpression(value) {
// eslint-disable-next-line global-require
const getValue = require('.').default;
return getValue(value.expression);
}

View File

@@ -0,0 +1,31 @@
/**
* Extractor function for a UnaryExpression type value node.
* A unary expression is an expression with a unary operator.
* For example, !"foobar" will evaluate to false, so this will return false.
*
* @param - value - AST Value object with type `UnaryExpression`
* @returns - The extracted value converted to correct type.
*/
export default function extractValueFromUnaryExpression(value) {
// eslint-disable-next-line global-require
const getValue = require('.').default;
const { operator, argument } = value;
switch (operator) {
case '-':
return -getValue(argument);
case '+':
return +getValue(argument); // eslint-disable-line no-implicit-coercion
case '!':
return !getValue(argument);
case '~':
return ~getValue(argument); // eslint-disable-line no-bitwise
case 'delete':
// I believe delete statements evaluate to true.
return true;
case 'typeof':
case 'void':
default:
return undefined;
}
}

View File

@@ -0,0 +1,24 @@
/**
* Extractor function for an UpdateExpression type value node.
* An update expression is an expression with an update operator.
* For example, foo++ will evaluate to foo + 1.
*
* @param - value - AST Value object with type `UpdateExpression`
* @returns - The extracted value converted to correct type.
*/
export default function extractValueFromUpdateExpression(value) {
// eslint-disable-next-line global-require
const getValue = require('.').default;
const { operator, argument, prefix } = value;
let val = getValue(argument);
switch (operator) {
case '++':
return prefix ? ++val : val++; // eslint-disable-line no-plusplus
case '--':
return prefix ? --val : val--; // eslint-disable-line no-plusplus
default:
return undefined;
}
}

View File

@@ -0,0 +1,184 @@
import Literal from '../Literal';
import JSXElement from '../JSXElement';
import JSXFragment from '../JSXFragment';
import JSXText from '../JSXText';
import Identifier from './Identifier';
import TaggedTemplateExpression from './TaggedTemplateExpression';
import TemplateLiteral from './TemplateLiteral';
import FunctionExpression from './FunctionExpression';
import LogicalExpression from './LogicalExpression';
import MemberExpression from './MemberExpression';
import ChainExpression from './ChainExpression';
import OptionalCallExpression from './OptionalCallExpression';
import OptionalMemberExpression from './OptionalMemberExpression';
import CallExpression from './CallExpression';
import UnaryExpression from './UnaryExpression';
import ThisExpression from './ThisExpression';
import ConditionalExpression from './ConditionalExpression';
import BinaryExpression from './BinaryExpression';
import ObjectExpression from './ObjectExpression';
import NewExpression from './NewExpression';
import UpdateExpression from './UpdateExpression';
import ArrayExpression from './ArrayExpression';
import BindExpression from './BindExpression';
import SpreadElement from './SpreadElement';
import TypeCastExpression from './TypeCastExpression';
import SequenceExpression from './SequenceExpression';
import TSNonNullExpression from './TSNonNullExpression';
import AssignmentExpression from './AssignmentExpression';
// Composition map of types to their extractor functions.
const TYPES = {
Identifier,
Literal,
JSXElement,
JSXFragment,
JSXText,
TaggedTemplateExpression,
TemplateLiteral,
ArrowFunctionExpression: FunctionExpression,
FunctionExpression,
LogicalExpression,
MemberExpression,
ChainExpression,
OptionalCallExpression,
OptionalMemberExpression,
CallExpression,
UnaryExpression,
ThisExpression,
ConditionalExpression,
BinaryExpression,
ObjectExpression,
NewExpression,
UpdateExpression,
ArrayExpression,
BindExpression,
SpreadElement,
TypeCastExpression,
SequenceExpression,
TSNonNullExpression,
AssignmentExpression,
};
const noop = () => null;
const errorMessage = (expression) => `The prop value with an expression type of ${expression} could not be resolved. Please file an issue ( https://github.com/jsx-eslint/jsx-ast-utils/issues/new ) to get this fixed immediately.`;
/**
* This function maps an AST value node
* to its correct extractor function for its
* given type.
*
* This will map correctly for *all* possible expression types.
*
* @param - value - AST Value object with type `JSXExpressionContainer`
* @returns The extracted value.
*/
export default function extract(value) {
// Value will not have the expression property when we recurse.
// The type for expression on ArrowFunctionExpression is a boolean.
let expression;
if (
typeof value.expression !== 'boolean'
&& value.expression
) {
expression = value.expression; // eslint-disable-line prefer-destructuring
} else {
expression = value;
}
let { type } = expression;
// Typescript NonNull Expression is wrapped & it would end up in the wrong extractor
if (expression.object && expression.object.type === 'TSNonNullExpression') {
type = 'TSNonNullExpression';
}
while (type === 'TSAsExpression') {
({ type } = expression);
if (expression.expression) {
({ expression } = expression);
}
}
if (TYPES[type] === undefined) {
// eslint-disable-next-line no-console
console.error(errorMessage(type));
return null;
}
return TYPES[type](expression);
}
// Composition map of types to their extractor functions to handle literals.
const LITERAL_TYPES = {
...TYPES,
Literal: (value) => {
const extractedVal = TYPES.Literal.call(undefined, value);
const isNull = extractedVal === null;
// This will be convention for attributes that have null
// value explicitly defined (<div prop={null} /> maps to 'null').
return isNull ? 'null' : extractedVal;
},
Identifier: (value) => {
const isUndefined = TYPES.Identifier.call(undefined, value) === undefined;
return isUndefined ? undefined : null;
},
JSXElement: noop,
JSXFragment: noop,
JSXText: noop,
ArrowFunctionExpression: noop,
FunctionExpression: noop,
LogicalExpression: noop,
MemberExpression: noop,
OptionalCallExpression: noop,
OptionalMemberExpression: noop,
CallExpression: noop,
UnaryExpression: (value) => {
const extractedVal = TYPES.UnaryExpression.call(undefined, value);
return extractedVal === undefined ? null : extractedVal;
},
UpdateExpression: (value) => {
const extractedVal = TYPES.UpdateExpression.call(undefined, value);
return extractedVal === undefined ? null : extractedVal;
},
ThisExpression: noop,
ConditionalExpression: noop,
BinaryExpression: noop,
ObjectExpression: noop,
NewExpression: noop,
ArrayExpression: (value) => {
const extractedVal = TYPES.ArrayExpression.call(undefined, value);
return extractedVal.filter((val) => val !== null);
},
BindExpression: noop,
SpreadElement: noop,
TSNonNullExpression: noop,
TSAsExpression: noop,
TypeCastExpression: noop,
SequenceExpression: noop,
ChainExpression: noop,
};
/**
* This function maps an AST value node
* to its correct extractor function for its
* given type.
*
* This will map correctly for *some* possible types that map to literals.
*
* @param - value - AST Value object with type `JSXExpressionContainer`
* @returns The extracted value.
*/
export function extractLiteral(value) {
// Value will not have the expression property when we recurse.
const expression = value.expression || value;
const { type } = expression;
if (LITERAL_TYPES[type] === undefined) {
// eslint-disable-next-line no-console
console.error(errorMessage(type));
return null;
}
return LITERAL_TYPES[type](expression);
}

48
node_modules/jsx-ast-utils/src/values/index.js generated vendored Normal file
View File

@@ -0,0 +1,48 @@
import Literal from './Literal';
import JSXElement from './JSXElement';
import JSXText from './JSXText';
import JSXFragment from './JSXFragment';
import JSXExpressionContainer, { extractLiteral } from './expressions';
// Composition map of types to their extractor functions.
const TYPES = {
Literal,
JSXElement,
JSXExpressionContainer,
JSXText,
JSXFragment,
};
// Composition map of types to their extractor functions to handle literals.
const LITERAL_TYPES = {
...TYPES,
JSXElement: () => null,
JSXExpressionContainer: extractLiteral,
};
/**
* This function maps an AST value node
* to its correct extractor function for its
* given type.
*
* This will map correctly for *all* possible types.
*
* @param value - AST Value object on a JSX Attribute.
*/
export default function getValue(value) {
if (!TYPES[value.type]) console.log(value.type);
return TYPES[value.type](value);
}
/**
* This function maps an AST value node
* to its correct extractor function for its
* given type.
*
* This will map correctly for *some* possible types that map to literals.
*
* @param value - AST Value object on a JSX Attribute.
*/
export function getLiteralValue(value) {
return LITERAL_TYPES[value.type](value);
}