@teleporthq/teleport-shared
Advanced tools
Comparing version 0.8.1 to 0.9.0
import { | ||
createDefaultExport, | ||
generateStyledJSXTag, | ||
createConstAssignment, | ||
createJSXSpreadAttribute, | ||
createGenericImportStatement, | ||
generateASTDefinitionForJSXTag, | ||
createJSXTag, | ||
createSelfClosingJSXTag, | ||
createFunctionCall, | ||
createFunctionalComponent, | ||
} from '../../src/builders/ast-builders' | ||
import * as types from '@babel/types' | ||
describe('AST builder', () => { | ||
describe('createConstAssignment', () => { | ||
it('should creat assignment for a const', () => { | ||
const result = createConstAssignment('testConst') | ||
expect(result.type).toBe('VariableDeclaration') | ||
expect(result.kind).toBe('const') | ||
expect(result.declarations[0].type).toBe('VariableDeclarator') | ||
expect(result.declarations[0].id.name).toBe('testConst') | ||
}) | ||
describe('createConstAssignment', () => { | ||
it('should creat assignment for a const', () => { | ||
const result = createConstAssignment('testConst') | ||
expect(result.type).toBe('VariableDeclaration') | ||
expect(result.kind).toBe('const') | ||
expect(result.declarations[0].type).toBe('VariableDeclarator') | ||
expect((result.declarations[0].id as types.Identifier).name).toBe('testConst') | ||
}) | ||
describe('createDefaultExport', () => { | ||
it('should creat default export', () => { | ||
const result = createDefaultExport('testConst') | ||
expect(result.type).toBe('ExportDefaultDeclaration') | ||
expect(result.declaration).toHaveProperty('name') | ||
expect(result.declaration.name).toBe('testConst') | ||
}) | ||
}) | ||
describe('createDefaultExport', () => { | ||
it('should creat default export', () => { | ||
const result = createDefaultExport('testConst') | ||
expect(result.type).toBe('ExportDefaultDeclaration') | ||
expect(result.declaration).toHaveProperty('name') | ||
expect((result.declaration as types.Identifier).name).toBe('testConst') | ||
}) | ||
}) | ||
describe('createGenericImportStatement', () => { | ||
it('should creat generic import statements', () => { | ||
const imports = [ | ||
{ identifier: 'Card', namedImport: false, originalName: 'Card' }, | ||
{ identifier: 'React', namedImport: false, originalName: 'React' }, | ||
{ identifier: 'useState', namedImport: true, originalName: 'useState' }, | ||
] | ||
const result = createGenericImportStatement('../testConst', imports) | ||
expect(result.type).toBe('ImportDeclaration') | ||
expect(result.specifiers.length).toEqual(imports.length) | ||
expect(result.source).toHaveProperty('value') | ||
expect(result.source.value).toBe('../testConst') | ||
}) | ||
it('should creat generic import statements if no import array is provided', () => { | ||
const result = createGenericImportStatement('../testConst', []) | ||
expect(result.type).toBe('ImportDeclaration') | ||
expect(result.source).toHaveProperty('value') | ||
expect(result.source.value).toBe('../testConst') | ||
}) | ||
describe('createGenericImportStatement', () => { | ||
it('should creat generic import statements', () => { | ||
const imports = [ | ||
{ identifierName: 'Card', namedImport: false, originalName: 'Card' }, | ||
{ identifierName: 'React', namedImport: false, originalName: 'React' }, | ||
{ identifierName: 'useState', namedImport: true, originalName: 'useState' }, | ||
] | ||
const result = createGenericImportStatement('../testConst', imports) | ||
expect(result.type).toBe('ImportDeclaration') | ||
expect(result.specifiers.length).toEqual(imports.length) | ||
expect(result.source).toHaveProperty('value') | ||
expect(result.source.value).toBe('../testConst') | ||
}) | ||
it('should creat generic import statements if no import array is provided', () => { | ||
const result = createGenericImportStatement('../testConst', []) | ||
expect(result.type).toBe('ImportDeclaration') | ||
expect(result.source).toHaveProperty('value') | ||
expect(result.source.value).toBe('../testConst') | ||
}) | ||
}) | ||
describe('generateStyledJSXTag', () => { | ||
it('returns JSXTag', () => { | ||
const result = generateStyledJSXTag('randomString') | ||
describe('createJSXTag', () => { | ||
it('returns a valid JSX tag', () => { | ||
const result = createJSXTag('randomString') | ||
expect(result.type).toBe('JSXElement') | ||
expect(result.openingElement.type).toBe('JSXOpeningElement') | ||
expect(result.openingElement.name).toHaveProperty('name', 'style') | ||
expect(result.closingElement.type).toBe('JSXClosingElement') | ||
expect(result.closingElement.name).toHaveProperty('name', 'style') | ||
}) | ||
expect(result.type).toBe('JSXElement') | ||
expect(result.openingElement.type).toBe('JSXOpeningElement') | ||
expect(result.openingElement.name).toHaveProperty('name', 'randomString') | ||
expect(result.closingElement.type).toBe('JSXClosingElement') | ||
expect(result.closingElement.name).toHaveProperty('name', 'randomString') | ||
}) | ||
}) | ||
describe('generateASTDefinitionForJSXTag', () => { | ||
it('returns ASTDefinitionForJSXTag', () => { | ||
const result = generateASTDefinitionForJSXTag('randomString') | ||
describe('createSelfClosingJSXTag', () => { | ||
it('returns a valid JSX tag', () => { | ||
const result = createSelfClosingJSXTag('randomString') | ||
expect(result.type).toBe('JSXElement') | ||
expect(result.openingElement.type).toBe('JSXOpeningElement') | ||
expect(result.openingElement.name).toHaveProperty('name', 'randomString') | ||
expect(result.closingElement.type).toBe('JSXClosingElement') | ||
expect(result.closingElement.name).toHaveProperty('name', 'randomString') | ||
}) | ||
expect(result.type).toBe('JSXElement') | ||
expect(result.openingElement.type).toBe('JSXOpeningElement') | ||
expect(result.openingElement.name).toHaveProperty('name', 'randomString') | ||
expect(result.selfClosing).toBe(true) | ||
}) | ||
}) | ||
describe('createJSXSpreadAttribute', () => { | ||
it('runs with success', () => { | ||
const result = createJSXSpreadAttribute('randomString') | ||
describe('createFunctionCall', () => { | ||
it('works with no arguments', () => { | ||
const result = createFunctionCall('console.log', []) | ||
expect(result.type).toBe('JSXSpreadAttribute') | ||
expect(result.argument).toHaveProperty('name', 'randomString') | ||
}) | ||
expect(result.type).toBe('CallExpression') | ||
expect(result.arguments.length).toBe(0) | ||
expect((result.callee as types.Identifier).name).toBe('console.log') | ||
}) | ||
it('works with arguments of different types', () => { | ||
const result = createFunctionCall('console.log', [0, '1']) | ||
expect(result.type).toBe('CallExpression') | ||
expect(result.arguments.length).toBe(2) | ||
expect(result.arguments[0].type).toBe('NumericLiteral') | ||
expect(result.arguments[1].type).toBe('StringLiteral') | ||
expect((result.callee as types.Identifier).name).toBe('console.log') | ||
}) | ||
it('works with AST as arguments', () => { | ||
const result = createFunctionCall('console.log', [0, createJSXTag('App')]) | ||
expect(result.type).toBe('CallExpression') | ||
expect(result.arguments.length).toBe(2) | ||
expect(result.arguments[0].type).toBe('NumericLiteral') | ||
expect(result.arguments[1].type).toBe('JSXElement') | ||
expect((result.callee as types.Identifier).name).toBe('console.log') | ||
}) | ||
}) | ||
describe('createFunctionalComponent', () => { | ||
it('returns a valid AST node', () => { | ||
const result = createFunctionalComponent('MyComponent', createSelfClosingJSXTag('App')) | ||
expect(result.type).toBe('VariableDeclaration') | ||
expect((result.declarations[0].id as types.Identifier).name).toBe('MyComponent') | ||
}) | ||
}) |
@@ -1,12 +0,136 @@ | ||
import { stringAsTemplateLiteral } from '../../src/utils/ast-jsx-utils' | ||
import { | ||
stringAsTemplateLiteral, | ||
addSpreadAttributeToJSXTag, | ||
renameJSXTag, | ||
addClassStringOnJSXTag, | ||
addAttributeToJSXTag, | ||
addDynamicAttributeToJSXTag, | ||
} from '../../src/utils/ast-jsx-utils' | ||
import { createJSXTag } from '../../src/builders/ast-builders' | ||
import { | ||
JSXSpreadAttribute, | ||
JSXIdentifier, | ||
JSXAttribute, | ||
StringLiteral, | ||
JSXExpressionContainer, | ||
Identifier, | ||
NumberLiteral, | ||
} from '@babel/types' | ||
describe('AST JSX utils', () => { | ||
describe('stringAsTemplateLiteral', () => { | ||
it('returns TemplateLiteral', () => { | ||
const result = stringAsTemplateLiteral('randomString') | ||
describe('stringAsTemplateLiteral', () => { | ||
it('returns TemplateLiteral', () => { | ||
const result = stringAsTemplateLiteral('randomString') | ||
expect(result.type).toBe('TemplateLiteral') | ||
expect(result.quasis[0].type).toBe('TemplateElement') | ||
}) | ||
expect(result.type).toBe('TemplateLiteral') | ||
expect(result.quasis[0].type).toBe('TemplateElement') | ||
}) | ||
}) | ||
describe('addSpreadAttributeToJSXTag', () => { | ||
it('runs with success', () => { | ||
const tag = createJSXTag('random') | ||
addSpreadAttributeToJSXTag(tag, 'randomString') | ||
const attr = tag.openingElement.attributes[0] | ||
expect(attr.type).toBe('JSXSpreadAttribute') | ||
expect((attr as JSXSpreadAttribute).argument).toHaveProperty('name', 'randomString') | ||
}) | ||
}) | ||
describe('renameJSXTag', () => { | ||
it('runs with success', () => { | ||
const tag = createJSXTag('random') | ||
renameJSXTag(tag, 'NewName') | ||
const openTag = tag.openingElement.name as JSXIdentifier | ||
const closeTag = tag.closingElement.name as JSXIdentifier | ||
expect(openTag.name).toBe('NewName') | ||
expect(closeTag.name).toBe('NewName') | ||
}) | ||
}) | ||
describe('addClassStringOnJSXTag', () => { | ||
it('adds a class on an element with no classes', () => { | ||
const tag = createJSXTag('button') | ||
addClassStringOnJSXTag(tag, 'primary') | ||
expect(tag.openingElement.attributes[0].type).toBe('JSXAttribute') | ||
const classAttr = tag.openingElement.attributes[0] as JSXAttribute | ||
expect(classAttr.name.name).toBe('className') | ||
expect((classAttr.value as StringLiteral).value).toBe('primary') | ||
}) | ||
it('adds a class on an element with existing classes', () => { | ||
const tag = createJSXTag('button') | ||
addAttributeToJSXTag(tag, 'className', 'button') | ||
addClassStringOnJSXTag(tag, 'primary') | ||
expect(tag.openingElement.attributes[0].type).toBe('JSXAttribute') | ||
const classAttr = tag.openingElement.attributes[0] as JSXAttribute | ||
expect(classAttr.name.name).toBe('className') | ||
expect((classAttr.value as StringLiteral).value).toBe('button primary') | ||
}) | ||
}) | ||
describe('addAttributeToJSXTag', () => { | ||
it('adds an attribute with no value', () => { | ||
const tag = createJSXTag('button') | ||
addAttributeToJSXTag(tag, 'disabled') | ||
expect(tag.openingElement.attributes[0].type).toBe('JSXAttribute') | ||
const classAttr = tag.openingElement.attributes[0] as JSXAttribute | ||
expect(classAttr.name.name).toBe('disabled') | ||
expect(classAttr.value).toBe(null) | ||
}) | ||
it('adds an attribute with the selected value', () => { | ||
const tag = createJSXTag('button') | ||
addAttributeToJSXTag(tag, 'data-attr', 'random-value') | ||
expect(tag.openingElement.attributes[0].type).toBe('JSXAttribute') | ||
const classAttr = tag.openingElement.attributes[0] as JSXAttribute | ||
expect(classAttr.name.name).toBe('data-attr') | ||
expect((classAttr.value as StringLiteral).value).toBe('random-value') | ||
}) | ||
it('adds an attribute as a JSX expression when non-string', () => { | ||
const tag = createJSXTag('button') | ||
addAttributeToJSXTag(tag, 'data-attr', 1) | ||
expect(tag.openingElement.attributes[0].type).toBe('JSXAttribute') | ||
const classAttr = tag.openingElement.attributes[0] as JSXAttribute | ||
expect(classAttr.name.name).toBe('data-attr') | ||
expect(((classAttr.value as JSXExpressionContainer).expression as NumberLiteral).value).toBe(1) | ||
}) | ||
}) | ||
describe('addDynamicAttributeToJSXTag', () => { | ||
it('adds the dynamic JSX expression on the opening tag', () => { | ||
const tag = createJSXTag('button') | ||
addDynamicAttributeToJSXTag(tag, 'dynamicValue', 'title') | ||
expect(tag.openingElement.attributes[0].type).toBe('JSXAttribute') | ||
const dynamicAttr = tag.openingElement.attributes[0] as JSXAttribute | ||
expect(dynamicAttr.value.type).toBe('JSXExpressionContainer') | ||
expect(((dynamicAttr.value as JSXExpressionContainer).expression as Identifier).name).toBe( | ||
'title' | ||
) | ||
}) | ||
it('adds the dynamic JSX expression on the opening tag with prefix', () => { | ||
const tag = createJSXTag('button') | ||
addDynamicAttributeToJSXTag(tag, 'dynamicValue', 'title', 'props') | ||
expect(tag.openingElement.attributes[0].type).toBe('JSXAttribute') | ||
const dynamicAttr = tag.openingElement.attributes[0] as JSXAttribute | ||
expect(dynamicAttr.value.type).toBe('JSXExpressionContainer') | ||
expect((dynamicAttr.value as JSXExpressionContainer).expression.type).toBe('MemberExpression') | ||
}) | ||
}) |
{ | ||
"name": "@teleporthq/teleport-shared", | ||
"version": "0.8.1", | ||
"version": "0.9.0", | ||
"description": "A utility belt for the entire teleportHQ ecosystem", | ||
@@ -8,4 +8,5 @@ "author": "teleportHQ", | ||
"homepage": "https://teleporthq.io/", | ||
"main": "lib/index.js", | ||
"types": "lib/index.d.ts", | ||
"main": "dist/cjs/index.js", | ||
"types": "dist/cjs/index.d.ts", | ||
"module": "dist/esm/index.js", | ||
"repository": { | ||
@@ -22,14 +23,14 @@ "type": "git", | ||
"scripts": { | ||
"clean": "rimraf lib", | ||
"build": "tsc", | ||
"build:watch": "tsc -w", | ||
"build:watch:core": "tsc -w" | ||
"clean": "rimraf dist", | ||
"build": "npm run build:cjs & npm run build:esm", | ||
"build:cjs": "tsc -p tsconfig-cjs.json", | ||
"build:esm": "tsc -p tsconfig-esm.json" | ||
}, | ||
"dependencies": { | ||
"@babel/types": "^7.3.3", | ||
"@teleporthq/teleport-types": "^0.8.1", | ||
"@teleporthq/teleport-types": "^0.9.0", | ||
"jss": "^9.8.7", | ||
"jss-preset-default": "^4.5.0" | ||
}, | ||
"gitHead": "73055f1b260190a3848f91fd6ce342e17a971369" | ||
"gitHead": "596c96d8a650d6a7a91d34e16e4d21b03db58096" | ||
} |
import * as types from '@babel/types' | ||
import { stringAsTemplateLiteral, addAttributeToJSXTag } from '../utils/ast-jsx-utils' | ||
import { convertValueToLiteral } from '../utils/ast-js-utils' | ||
import { ImportIdentifier } from '@teleporthq/teleport-types' | ||
@@ -10,6 +11,18 @@ export const createConstAssignment = (constName: string, asignment: any = null, t = types) => { | ||
export const createDefaultExport = (name: string, t = types) => { | ||
return t.exportDefaultDeclaration(t.identifier(name)) | ||
export const createDefaultExport = (exportReference: string, t = types) => { | ||
return t.exportDefaultDeclaration(t.identifier(exportReference)) | ||
} | ||
export const createReactJSSDefaultExport = ( | ||
componentName: string, | ||
stylesName: string, | ||
t = types | ||
) => { | ||
return t.exportDefaultDeclaration( | ||
t.callExpression(t.callExpression(t.identifier('injectSheet'), [t.identifier(stylesName)]), [ | ||
t.identifier(componentName), | ||
]) | ||
) | ||
} | ||
/** | ||
@@ -19,13 +32,23 @@ * You can pass the path of the package which is added at the top of the file and | ||
*/ | ||
export const createGenericImportStatement = (path: string, imports: any[], t = types) => { | ||
export const createGenericImportStatement = ( | ||
path: string, | ||
imports: ImportIdentifier[], | ||
t = types | ||
) => { | ||
// Only one of the imports can be the default one so this is a fail safe for invalid UIDL data | ||
const defaultImport = imports.find((imp) => !imp.namedImport) // only one import can be default | ||
const importJustPath = imports.some((imp) => imp.importJustPath) | ||
let importASTs: any[] = [] | ||
if (defaultImport) { | ||
const namedImports = imports.filter((imp) => imp.identifier !== defaultImport.identifier) | ||
if (importJustPath) { | ||
// Just the import path will be present, eg: import './styles.css' | ||
importASTs = [] | ||
} else if (defaultImport) { | ||
const namedImports = imports.filter( | ||
(imp) => imp.identifierName !== defaultImport.identifierName | ||
) | ||
// Default import needs to be the first in the array | ||
importASTs = [ | ||
t.importDefaultSpecifier(t.identifier(defaultImport.identifier)), | ||
t.importDefaultSpecifier(t.identifier(defaultImport.identifierName)), | ||
...namedImports.map((imp) => | ||
t.importSpecifier(t.identifier(imp.identifier), t.identifier(imp.originalName)) | ||
t.importSpecifier(t.identifier(imp.identifierName), t.identifier(imp.originalName)) | ||
), | ||
@@ -36,3 +59,3 @@ ] | ||
importASTs = imports.map((imp) => | ||
t.importSpecifier(t.identifier(imp.identifier), t.identifier(imp.originalName)) | ||
t.importSpecifier(t.identifier(imp.identifierName), t.identifier(imp.originalName)) | ||
) | ||
@@ -43,54 +66,77 @@ } | ||
// TODO: Use generateASTDefinitionForJSXTag instead? | ||
export const generateStyledJSXTag = ( | ||
templateLiteral: string | types.TemplateLiteral, | ||
type JSXChild = | ||
| types.JSXText | ||
| types.JSXExpressionContainer | ||
| types.JSXSpreadChild | ||
| types.JSXElement | ||
| types.JSXFragment | ||
export const createJSXTag = ( | ||
tagName: string, | ||
children: JSXChild[] = [], | ||
selfClosing = false, | ||
t = types | ||
) => { | ||
if (typeof templateLiteral === 'string') { | ||
templateLiteral = stringAsTemplateLiteral(templateLiteral, t) | ||
} | ||
const jsxIdentifier = t.jsxIdentifier(tagName) | ||
const openingTag = t.jsxOpeningElement(jsxIdentifier, [], selfClosing) | ||
const closingTag = t.jsxClosingElement(jsxIdentifier) | ||
const jsxTagChild = t.jsxExpressionContainer(templateLiteral) | ||
const jsxTag = generateBasicJSXTag('style', [jsxTagChild, t.jsxText('\n')], t) | ||
addAttributeToJSXTag(jsxTag, { name: 'jsx' }, t) | ||
return jsxTag | ||
const tag = t.jsxElement(openingTag, closingTag, children, selfClosing) | ||
return tag | ||
} | ||
const generateBasicJSXTag = (tagName: string, children: any[] = [], t = types) => { | ||
const jsxIdentifier = t.jsxIdentifier(tagName) | ||
const openingDiv = t.jsxOpeningElement(jsxIdentifier, [], false) | ||
const closingDiv = t.jsxClosingElement(jsxIdentifier) | ||
export const createSelfClosingJSXTag = (tagName: string) => { | ||
return createJSXTag(tagName, [], true) | ||
} | ||
const tag = t.jsxElement(openingDiv, closingDiv, children, false) | ||
export const createJSXExpresionContainer = (expression: types.Expression, t = types) => { | ||
return t.jsxExpressionContainer(expression) | ||
} | ||
return tag | ||
export const createFunctionCall = (functionName: string, args: any[] = [], t = types) => { | ||
const convertedArgs = args.map((value) => { | ||
// skip objects which are already in AST format | ||
if (objectIsASTType(value)) { | ||
return value | ||
} | ||
return convertValueToLiteral(value) | ||
}) | ||
return t.callExpression(t.identifier(functionName), convertedArgs) | ||
} | ||
/** | ||
* Generates the AST definiton (without start/end position) for a JSX tag | ||
* with an opening and closing tag. | ||
* | ||
* t is the babel-types api which generates the JSON structure representing the AST. | ||
* This is set as a parameter to allow us to remove babel-types at some point if we | ||
* decide to, and to allow easier unit testing of the utils. | ||
* | ||
* Requires the tagName, which is a string that will be used to generate the | ||
* tag. | ||
* | ||
* Example: | ||
* generateASTDefinitionForJSXTag("div") will generate the AST | ||
* equivalent of <div></div> | ||
*/ | ||
export const generateASTDefinitionForJSXTag = (tagName: string, t = types) => { | ||
const jsxIdentifier = t.jsxIdentifier(tagName) | ||
const openingDiv = t.jsxOpeningElement(jsxIdentifier, [], false) | ||
const closingDiv = t.jsxClosingElement(jsxIdentifier) | ||
const objectIsASTType = (obj: any) => { | ||
if (typeof obj !== 'object') { | ||
return false | ||
} | ||
const tag = t.jsxElement(openingDiv, closingDiv, [], false) | ||
// TODO: extensive list | ||
return obj.type === 'JSXElement' || obj.type === 'CallExpression' | ||
} | ||
return tag | ||
// equivalent to (props) => props.title | ||
export const createArrowFunctionWithMemberExpression = ( | ||
argument: string, | ||
returnIdentifier: string, | ||
t = types | ||
) => { | ||
return t.arrowFunctionExpression( | ||
[t.identifier(argument)], | ||
t.memberExpression(t.identifier(argument), t.identifier(returnIdentifier)) | ||
) | ||
} | ||
export const createJSXSpreadAttribute = (name: string, t = types) => { | ||
return t.jsxSpreadAttribute(t.identifier(name)) | ||
export const createFunctionalComponent = ( | ||
componentName: string, | ||
jsxRoot: types.JSXElement, | ||
t = types | ||
) => { | ||
const returnStatement = t.returnStatement(jsxRoot) | ||
const arrowFunction = t.arrowFunctionExpression([], t.blockStatement([returnStatement] || [])) | ||
const declarator = t.variableDeclarator(t.identifier(componentName), arrowFunction) | ||
const component = t.variableDeclaration('const', [declarator]) | ||
return component | ||
} |
import jss from 'jss' | ||
import preset from 'jss-preset-default' | ||
import * as types from '@babel/types' | ||
import { UIDLDynamicReference } from '@teleporthq/teleport-types' | ||
import { ParsedASTNode } from '../utils/ast-js-utils' | ||
@@ -18,1 +21,25 @@ jss.setup(preset()) | ||
} | ||
export const createDynamicStyleExpression = ( | ||
styleValue: UIDLDynamicReference, | ||
propsPrefix: string = '', | ||
t = types | ||
) => { | ||
switch (styleValue.content.referenceType) { | ||
case 'state': | ||
case 'local': | ||
return new ParsedASTNode(t.identifier(styleValue.content.id)) | ||
case 'prop': | ||
return new ParsedASTNode( | ||
t.memberExpression(t.identifier(propsPrefix), t.identifier(styleValue.content.id)) | ||
) | ||
default: | ||
throw new Error( | ||
`createDynamicStyleExpression received unsupported ${JSON.stringify( | ||
styleValue, | ||
null, | ||
2 | ||
)} UIDLDynamicReference value` | ||
) | ||
} | ||
} |
import { | ||
ComponentUIDL, | ||
ReferenceType, | ||
ComponentDependency, | ||
UIDLDependency, | ||
UIDLNode, | ||
@@ -46,3 +46,3 @@ UIDLSlotNode, | ||
children?: UIDLNode[], | ||
dependency?: ComponentDependency, | ||
dependency?: UIDLDependency, | ||
style?: Record<string, UIDLStyleValue> | ||
@@ -62,9 +62,18 @@ ): UIDLElementNode => { | ||
children?: UIDLNode[], | ||
dependency?: ComponentDependency, | ||
dependency?: UIDLDependency, | ||
style?: Record<string, UIDLStyleValue> | ||
) => { | ||
if (dependency) { | ||
return { | ||
elementType, | ||
name: elementType, | ||
dependency, | ||
attrs, | ||
style, | ||
children, | ||
} | ||
} | ||
return { | ||
elementType, | ||
name: elementType, | ||
dependency, | ||
attrs, | ||
@@ -81,3 +90,3 @@ style, | ||
meta?: Record<string, string | boolean> | ||
): ComponentDependency => { | ||
): UIDLDependency => { | ||
return { | ||
@@ -108,3 +117,6 @@ type, | ||
export const slotNode = (fallback?: UIDLNode, name?: string): UIDLSlotNode => { | ||
export const slotNode = ( | ||
fallback?: UIDLElementNode | UIDLStaticValue | UIDLDynamicReference, | ||
name?: string | ||
): UIDLSlotNode => { | ||
return { | ||
@@ -111,0 +123,0 @@ type: 'slot', |
@@ -0,3 +1,5 @@ | ||
import { PrettierFormatOptions } from '@teleporthq/teleport-types' | ||
export const ASSETS_IDENTIFIER = '/playground_assets' | ||
export const PRETTIER_CONFIG = { | ||
export const PRETTIER_CONFIG: PrettierFormatOptions = { | ||
arrowParens: 'always', | ||
@@ -14,2 +16,3 @@ printWidth: 100, | ||
CSS: 'css', | ||
CSSMODULE: 'module.css', | ||
HTML: 'html', | ||
@@ -19,2 +22,10 @@ JS: 'js', | ||
VUE: 'vue', | ||
TS: 'ts', | ||
TSX: 'tsx', | ||
} | ||
export const CHUNK_TYPE = { | ||
AST: 'ast', | ||
HAST: 'hast', | ||
STRING: 'string', | ||
} |
@@ -87,1 +87,23 @@ import * as types from '@babel/types' | ||
} | ||
export const addPropertyToASTObject = ( | ||
obj: types.ObjectExpression, | ||
key: string, | ||
value: any, | ||
t = types | ||
) => { | ||
obj.properties.push(t.objectProperty(t.identifier(key), convertValueToLiteral(value))) | ||
} | ||
export const getTSAnnotationForType = (type: any, t = types) => { | ||
switch (type) { | ||
case 'string': | ||
return t.tsStringKeyword() | ||
case 'number': | ||
return t.tsNumberKeyword() | ||
case 'boolean': | ||
return t.tsBooleanKeyword() | ||
default: | ||
return t.tsUnknownKeyword() | ||
} | ||
} |
import * as types from '@babel/types' | ||
import { objectToObjectExpression, convertValueToLiteral } from './ast-js-utils' | ||
import { convertValueToLiteral } from './ast-js-utils' | ||
@@ -10,5 +10,5 @@ /** | ||
classString: string, | ||
t = types | ||
classAttributeName?: string | ||
) => { | ||
const classAttribute = getClassAttribute(jsxNode, { createIfNotFound: true }, t) | ||
const classAttribute = getClassAttribute(jsxNode, { createIfNotFound: true, classAttributeName }) | ||
if (classAttribute.value && classAttribute.value.type === 'StringLiteral') { | ||
@@ -31,11 +31,14 @@ const classArray = classAttribute.value.value.split(' ') | ||
jsxNode: types.JSXElement, | ||
params: { createIfNotFound: boolean } = { createIfNotFound: false }, | ||
{ createIfNotFound = false, classAttributeName = 'className' }, | ||
t = types | ||
): types.JSXAttribute => { | ||
const classNameAttribute = jsxNode.openingElement.attributes.find((attribute) => { | ||
return attribute.type === 'JSXAttribute' && attribute.name.name === 'className' | ||
return attribute.type === 'JSXAttribute' && attribute.name.name === classAttributeName | ||
}) | ||
if (!classNameAttribute && params.createIfNotFound) { | ||
const createdClassAttribute = t.jsxAttribute(t.jsxIdentifier('className'), t.stringLiteral('')) | ||
if (!classNameAttribute && createIfNotFound) { | ||
const createdClassAttribute = t.jsxAttribute( | ||
t.jsxIdentifier(classAttributeName), | ||
t.stringLiteral('') | ||
) | ||
@@ -51,8 +54,4 @@ jsxNode.openingElement.attributes.push(createdClassAttribute) | ||
* Makes `${name}={${prefix}.${value}}` happen in AST | ||
* | ||
* @param jsxASTNode the jsx ast element | ||
* @param name the name of the prop | ||
* @param value the value of the prop (will be concatenated with props. before it) | ||
*/ | ||
export const addDynamicAttributeOnTag = ( | ||
export const addDynamicAttributeToJSXTag = ( | ||
jsxASTNode: types.JSXElement, | ||
@@ -94,8 +93,9 @@ name: string, | ||
jsxNode: types.JSXElement, | ||
attribute: { name: string; value?: any }, | ||
attrName: string, | ||
attrValue?: any, | ||
t = types | ||
) => { | ||
const nameOfAttribute = t.jsxIdentifier(attribute.name) | ||
const nameOfAttribute = t.jsxIdentifier(attrName) | ||
let attributeDefinition | ||
if (typeof attribute.value === 'boolean') { | ||
if (typeof attrValue === 'boolean') { | ||
attributeDefinition = t.jsxAttribute(nameOfAttribute) | ||
@@ -105,3 +105,3 @@ } else { | ||
nameOfAttribute, | ||
getProperAttributeValueAssignment(attribute.value) | ||
getProperAttributeValueAssignment(attrValue) | ||
) | ||
@@ -140,9 +140,15 @@ } | ||
// TODO: Replace with generic add attribute? | ||
export const addJSXTagStyles = (tag: types.JSXElement, styleMap: any, t = types) => { | ||
const styleObjectExpression = objectToObjectExpression(styleMap, t) | ||
const styleObjectExpressionContainer = t.jsxExpressionContainer(styleObjectExpression) | ||
export const addSpreadAttributeToJSXTag = ( | ||
jsxTag: types.JSXElement, | ||
attrName: string, | ||
t = types | ||
) => { | ||
jsxTag.openingElement.attributes.push(t.jsxSpreadAttribute(t.identifier(attrName))) | ||
} | ||
const styleJSXAttr = t.jsxAttribute(t.jsxIdentifier('style'), styleObjectExpressionContainer) | ||
tag.openingElement.attributes.push(styleJSXAttr) | ||
export const renameJSXTag = (jsxTag: types.JSXElement, newName: string, t = types) => { | ||
jsxTag.openingElement.name = t.jsxIdentifier(newName) | ||
if (jsxTag.closingElement) { | ||
jsxTag.closingElement.name = t.jsxIdentifier(newName) | ||
} | ||
} |
@@ -76,2 +76,20 @@ import { ASSETS_IDENTIFIER } from '../constants' | ||
export const getStyleFileName = (component: ComponentUIDL) => { | ||
const componentFileName = getComponentFileName(component) | ||
// If component meta style file name is not set, we default to the component file name | ||
return component.meta && component.meta.styleFileName | ||
? component.meta.styleFileName | ||
: componentFileName | ||
} | ||
export const getTemplateFileName = (component: ComponentUIDL) => { | ||
const componentFileName = getComponentFileName(component) | ||
// If component meta style file name is not set, we default to the component file name | ||
return component.meta && component.meta.templateFileName | ||
? component.meta.templateFileName | ||
: componentFileName | ||
} | ||
export const getComponentPath = (component: ComponentUIDL) => | ||
@@ -78,0 +96,0 @@ component.meta ? component.meta.path : [] |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
665590
154
7158
1
+ Added@teleporthq/teleport-types@0.9.0(transitive)
- Removed@teleporthq/teleport-types@0.8.1(transitive)