@teleporthq/teleport-plugin-common
Advanced tools
Comparing version 0.31.0-alpha.0 to 0.31.0
@@ -1,2 +0,2 @@ | ||
import { createCSSClass, createCSSClassWithSelector } from '../../src/builders/style-builders' | ||
import { createCSSClass } from '../../src/builders/style-builders' | ||
@@ -18,13 +18,2 @@ describe('CSS Class Generation', () => { | ||
}) | ||
it('with subselectors', () => { | ||
const result = createCSSClassWithSelector('name', '& h1 > h2 .ab.cd #id', { | ||
someKey: 'value', | ||
otherKey: 'otherValue', | ||
}) | ||
expect(result).toEqual(`.name h1 > h2 .ab.cd #id { | ||
some-key: value; | ||
other-key: otherValue; | ||
}`) | ||
}) | ||
}) |
@@ -17,4 +17,4 @@ import * as types from '@babel/types' | ||
dependencies: {}, | ||
propDefinitions: uidl.propDefinitions || {}, | ||
stateDefinitions: uidl.stateDefinitions || {}, | ||
propDefinitions: uidl.propDefinitions, | ||
stateDefinitions: uidl.stateDefinitions, | ||
nodesLookup: {}, | ||
@@ -28,3 +28,2 @@ } | ||
local: '', | ||
ctx: '', | ||
}, | ||
@@ -31,0 +30,0 @@ } |
@@ -11,3 +11,3 @@ import * as types from '@babel/types'; | ||
export declare const createGenericImportStatement: (path: string, imports: ImportIdentifier[], t?: typeof types) => types.ImportDeclaration; | ||
declare type JSXChild = types.JSXText | types.JSXExpressionContainer | types.JSXSpreadChild | types.JSXElement | types.JSXFragment; | ||
type JSXChild = types.JSXText | types.JSXExpressionContainer | types.JSXSpreadChild | types.JSXElement | types.JSXFragment; | ||
export declare const createJSXTag: (tagName: string, children?: JSXChild[], selfClosing?: boolean, t?: typeof types) => types.JSXElement; | ||
@@ -14,0 +14,0 @@ export declare const createSelfClosingJSXTag: (tagName: string) => types.JSXElement; |
@@ -6,9 +6,10 @@ import * as types from '@babel/types'; | ||
export declare const createCSSClassWithSelector: (key: string, selector: string, styleObject: Record<string, string | number>) => string; | ||
export declare const createCSSClassWithMediaQuery: (mediaOffset: string, styleObject: Record<string, string | number | Record<string, string | number>>) => string; | ||
export declare const createFontDecleration: (styleObject: Record<string, string | number>) => string; | ||
export declare const createCSSClassWithMediaQuery: (mediaOffset: string, styleObject: Record<string, string | number>) => string; | ||
export declare const createDynamicStyleExpression: (styleValue: UIDLDynamicReference, propsPrefix?: string, t?: typeof types) => string | ParsedASTNode; | ||
export declare const generateMediaStyle: (styleMap: Record<string, { | ||
[x: string]: Record<string, string | number | Record<string, string | number>>; | ||
[x: string]: Record<string, string | number>; | ||
}[]>) => string[]; | ||
export declare const generateStylesFromStyleSetDefinitions: (styleSetDefinitions: Record<string, UIDLStyleSetDefinition>, cssMap: string[], mediaStylesMap: Record<string, { | ||
[x: string]: Record<string, string | number | Record<string, string | number>>; | ||
[x: string]: Record<string, string | number>; | ||
}[]>, className: (val: string) => string) => void; | ||
@@ -15,0 +16,0 @@ export declare const setPropValueForCompStyle: (params: { |
@@ -40,3 +40,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.setPropValueForCompStyle = exports.generateStylesFromStyleSetDefinitions = exports.generateMediaStyle = exports.createDynamicStyleExpression = exports.createCSSClassWithMediaQuery = exports.createCSSClassWithSelector = exports.createCSSClass = void 0; | ||
exports.setPropValueForCompStyle = exports.generateStylesFromStyleSetDefinitions = exports.generateMediaStyle = exports.createDynamicStyleExpression = exports.createCSSClassWithMediaQuery = exports.createFontDecleration = exports.createCSSClassWithSelector = exports.createCSSClass = void 0; | ||
var jss_1 = __importDefault(require("jss")); | ||
@@ -73,2 +73,10 @@ var jss_preset_default_1 = __importDefault(require("jss-preset-default")); | ||
exports.createCSSClassWithSelector = createCSSClassWithSelector; | ||
var createFontDecleration = function (styleObject) { | ||
return jss_1.default | ||
.createStyleSheet({ | ||
'@font-face': styleObject, | ||
}) | ||
.toString(); | ||
}; | ||
exports.createFontDecleration = createFontDecleration; | ||
var createCSSClassWithMediaQuery = function (mediaOffset, styleObject) { | ||
@@ -116,15 +124,10 @@ return jss_1.default | ||
var content = style.content, _a = style.conditions, conditions = _a === void 0 ? [] : _a, type = style.type; | ||
var name = className(style.className || styleId); | ||
var subselectors = style.subselectors; | ||
var name = className(styleId); | ||
var _b = teleport_shared_1.UIDLUtils.splitDynamicAndStaticStyles(content), staticStyles = _b.staticStyles, tokenStyles = _b.tokenStyles; | ||
var collectedStyles = __assign(__assign({}, (0, style_utils_1.getContentOfStyleObject)(staticStyles)), (0, style_utils_1.getCSSVariablesContentFromTokenStyles)(tokenStyles)); | ||
// & is required by jss, otherwise the final result will be empty | ||
var cls = subselectors | ||
? (0, exports.createCSSClassWithSelector)(name, "&".concat(subselectors), collectedStyles) | ||
: (0, exports.createCSSClass)(name, collectedStyles); | ||
if (type === 'reusable-component-style-map') { | ||
cssMap.unshift(cls); | ||
cssMap.unshift((0, exports.createCSSClass)(name, collectedStyles)); | ||
} | ||
else { | ||
cssMap.push(cls); | ||
cssMap.push((0, exports.createCSSClass)(name, collectedStyles)); | ||
} | ||
@@ -135,11 +138,11 @@ if (conditions.length === 0) { | ||
conditions.forEach(function (styleRef) { | ||
var _a, _b, _c; | ||
var _d = teleport_shared_1.UIDLUtils.splitDynamicAndStaticStyles(styleRef.content), staticValues = _d.staticStyles, tokenValues = _d.tokenStyles; | ||
var _a, _b; | ||
var _c = teleport_shared_1.UIDLUtils.splitDynamicAndStaticStyles(styleRef.content), staticValues = _c.staticStyles, tokenValues = _c.tokenStyles; | ||
var collecedMediaStyles = __assign(__assign({}, (0, style_utils_1.getContentOfStyleObject)(staticValues)), (0, style_utils_1.getCSSVariablesContentFromTokenStyles)(tokenValues)); | ||
if (styleRef.type === 'element-state') { | ||
if (type === 'reusable-component-style-map') { | ||
cssMap.unshift((0, exports.createCSSClassWithSelector)(name, "&".concat(subselectors || '', ":").concat(styleRef.meta.state), collecedMediaStyles)); | ||
cssMap.unshift((0, exports.createCSSClassWithSelector)(name, "&:".concat(styleRef.meta.state), collecedMediaStyles)); | ||
} | ||
else { | ||
cssMap.push((0, exports.createCSSClassWithSelector)(name, "&".concat(subselectors || '', ":").concat(styleRef.meta.state), collecedMediaStyles)); | ||
cssMap.push((0, exports.createCSSClassWithSelector)(name, "&:".concat(styleRef.meta.state), collecedMediaStyles)); | ||
} | ||
@@ -152,9 +155,7 @@ } | ||
} | ||
var mediaStyleMap = subselectors | ||
? (_a = {}, _a["&".concat(subselectors)] = collecedMediaStyles, _a) : collecedMediaStyles; | ||
if (type === 'reusable-component-style-map') { | ||
mediaStylesMap[String(maxWidth)].unshift((_b = {}, _b[name] = mediaStyleMap, _b)); | ||
mediaStylesMap[String(maxWidth)].unshift((_a = {}, _a[name] = collecedMediaStyles, _a)); | ||
} | ||
else { | ||
mediaStylesMap[String(maxWidth)].push((_c = {}, _c[name] = mediaStyleMap, _c)); | ||
mediaStylesMap[String(maxWidth)].push((_b = {}, _b[name] = collecedMediaStyles, _b)); | ||
} | ||
@@ -161,0 +162,0 @@ } |
@@ -98,2 +98,8 @@ "use strict"; | ||
switch (node.type) { | ||
case 'inject': | ||
if (node === null || node === void 0 ? void 0 : node.dependency) { | ||
/* tslint:disable:no-string-literal */ | ||
params.dependencies['Script'] = node.dependency; | ||
} | ||
return node.content.toString(); | ||
case 'raw': | ||
@@ -100,0 +106,0 @@ return generateRawHTMLNode(node, params, templateSyntax); |
@@ -21,3 +21,3 @@ import { UIDLDependency, UIDLEventHandlerStatement, UIDLElementNode } from '@teleporthq/teleport-types'; | ||
} | ||
export declare type NodeToHTML<NodeType, ReturnType> = (node: NodeType, params: HTMLTemplateGenerationParams, templateSyntax: HTMLTemplateSyntax) => ReturnType; | ||
export type NodeToHTML<NodeType, ReturnType> = (node: NodeType, params: HTMLTemplateGenerationParams, templateSyntax: HTMLTemplateSyntax) => ReturnType; | ||
//# sourceMappingURL=types.d.ts.map |
@@ -43,7 +43,6 @@ "use strict"; | ||
var constants_1 = require("./constants"); | ||
var __1 = require("../.."); | ||
var generateElementNode = function (node, params, jsxOptions) { | ||
var dependencies = params.dependencies, nodesLookup = params.nodesLookup, _a = params.projectResources, projectResources = _a === void 0 ? {} : _a; | ||
var options = __assign(__assign(__assign({}, constants_1.DEFAULT_JSX_OPTIONS), jsxOptions), { projectResources: projectResources }); | ||
var _b = node.content, elementType = _b.elementType, selfClosing = _b.selfClosing, children = _b.children, key = _b.key, attrs = _b.attrs, dependency = _b.dependency, events = _b.events; | ||
var options = __assign(__assign({}, constants_1.DEFAULT_JSX_OPTIONS), jsxOptions); | ||
var dependencies = params.dependencies, nodesLookup = params.nodesLookup; | ||
var _a = node.content, elementType = _a.elementType, selfClosing = _a.selfClosing, children = _a.children, key = _a.key, attrs = _a.attrs, dependency = _a.dependency, events = _a.events; | ||
var originalElementName = elementType || 'component'; | ||
@@ -78,9 +77,5 @@ var tagName = originalElementName; | ||
case 'dynamic': | ||
var referenceType = attributeValue.content.referenceType; | ||
switch (referenceType) { | ||
default: | ||
var prefix = options.dynamicReferencePrefixMap[referenceType]; | ||
(0, ast_utils_1.addDynamicAttributeToJSXTag)(elementTag, attrKey, attributeValue.content.id, prefix); | ||
break; | ||
} | ||
var _a = attributeValue.content, id = _a.id, referenceType = _a.referenceType; | ||
var prefix = options.dynamicReferencePrefixMap[referenceType]; | ||
(0, ast_utils_1.addDynamicAttributeToJSXTag)(elementTag, attrKey, id, prefix); | ||
break; | ||
@@ -95,7 +90,5 @@ case 'import': | ||
case 'static': | ||
(0, ast_utils_1.addAttributeToJSXTag)(elementTag, attrKey, attributeValue.content); | ||
var content = attributeValue.content; | ||
(0, ast_utils_1.addAttributeToJSXTag)(elementTag, attrKey, content); | ||
break; | ||
case 'expr': | ||
(0, ast_utils_1.addDynamicExpressionAttributeToJSXTag)(elementTag, attributeValue, attrKey); | ||
break; | ||
default: | ||
@@ -113,14 +106,12 @@ throw new Error("generateElementNode could not generate code for attribute of type ".concat(JSON.stringify(attributeValue))); | ||
children.forEach(function (child) { | ||
var childTags = generateNode(child, params, options); | ||
childTags.forEach(function (childTag) { | ||
if (typeof childTag === 'string') { | ||
(0, ast_utils_1.addChildJSXText)(elementTag, childTag); | ||
} | ||
else if (childTag.type === 'JSXExpressionContainer' || childTag.type === 'JSXElement') { | ||
(0, ast_utils_1.addChildJSXTag)(elementTag, childTag); | ||
} | ||
else { | ||
(0, ast_utils_1.addChildJSXTag)(elementTag, types.jsxExpressionContainer(childTag)); | ||
} | ||
}); | ||
var childTag = generateNode(child, params, options); | ||
if (typeof childTag === 'string') { | ||
(0, ast_utils_1.addChildJSXText)(elementTag, childTag); | ||
} | ||
else if (childTag.type === 'JSXExpressionContainer' || childTag.type === 'JSXElement') { | ||
(0, ast_utils_1.addChildJSXTag)(elementTag, childTag); | ||
} | ||
else { | ||
(0, ast_utils_1.addChildJSXTag)(elementTag, types.jsxExpressionContainer(childTag)); | ||
} | ||
}); | ||
@@ -134,19 +125,18 @@ } | ||
switch (node.type) { | ||
case 'expr': | ||
return [generateExpressionNode(node, params, options)]; | ||
case 'inject': | ||
if (node === null || node === void 0 ? void 0 : node.dependency) { | ||
/* tslint:disable:no-string-literal */ | ||
params.dependencies['Script'] = node.dependency; | ||
} | ||
return node.content.toString(); | ||
case 'raw': | ||
return [ | ||
options.domHTMLInjection | ||
? options.domHTMLInjection(node.content.toString()) | ||
: node.content.toString(), | ||
]; | ||
return options.domHTMLInjection | ||
? options.domHTMLInjection(node.content.toString()) | ||
: node.content.toString(); | ||
case 'static': | ||
return [teleport_shared_1.StringUtils.encode(node.content.toString())]; | ||
return teleport_shared_1.StringUtils.encode(node.content.toString()); | ||
case 'dynamic': | ||
return [(0, utils_1.createDynamicValueExpression)(node, options, undefined)]; | ||
case 'cms-item': | ||
case 'cms-list': | ||
return generateCMSNode(node, params, options); | ||
return (0, utils_1.createDynamicValueExpression)(node, options); | ||
case 'element': | ||
return [generateElementNode(node, params, options)]; | ||
return generateElementNode(node, params, options); | ||
case 'repeat': | ||
@@ -156,7 +146,5 @@ return generateRepeatNode(node, params, options); | ||
return generateConditionalNode(node, params, options); | ||
case 'cms-list-repeater': | ||
return generateCMSListRepeaterNode(node, params, options); | ||
case 'slot': | ||
if (options.slotHandling === 'native') { | ||
return [generateNativeSlotNode(node, params, options)]; | ||
return generateNativeSlotNode(node, params, options); | ||
} | ||
@@ -170,65 +158,8 @@ else { | ||
}; | ||
var generateExpressionNode = function (node) { | ||
var expression = __1.ASTUtils.getExpressionFromUIDLExpressionNode(node); | ||
return types.jsxExpressionContainer(expression); | ||
}; | ||
var generateCMSNode = function (node, params, options) { | ||
var _a = node.content, initialData = _a.initialData, key = _a.key, renderPropIdentifier = _a.renderPropIdentifier, _b = _a.resource, _c = _b === void 0 ? {} : _b, resourceParams = _c.params, router = _a.router, elementType = _a.elementType, dependency = _a.dependency; | ||
var _d = node.content.nodes, loading = _d.loading, error = _d.error, success = _d.success; | ||
var jsxTag = teleport_shared_1.StringUtils.dashCaseToUpperCamelCase(elementType); | ||
if (router && (options === null || options === void 0 ? void 0 : options.dependencyHandling) === 'import') { | ||
params.dependencies.useRouter = router; | ||
} | ||
if (!success) { | ||
return []; | ||
} | ||
if (dependency && options.dependencyHandling === 'import') { | ||
params.dependencies[elementType] = dependency; | ||
} | ||
var cmsNode = __1.ASTBuilders.createJSXTag(jsxTag, [], true); | ||
if (node.type === 'cms-item') { | ||
cmsNode.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('renderSuccess'), types.jsxExpressionContainer(types.arrowFunctionExpression([types.identifier(renderPropIdentifier)], generateNode(success, params, options)[0])))); | ||
} | ||
if (node.type === 'cms-list') { | ||
cmsNode.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('renderSuccess'), types.jsxExpressionContainer(types.arrowFunctionExpression([types.identifier('params')], generateNode(success, params, options)[0])))); | ||
} | ||
if (dependency && options.dependencyHandling === 'import') { | ||
params.dependencies.Repeater = dependency; | ||
} | ||
if (loading) { | ||
cmsNode.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('renderLoading'), types.jsxExpressionContainer(types.arrowFunctionExpression([], generateNode(loading, params, options)[0])))); | ||
} | ||
if (error) { | ||
cmsNode.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('renderError'), types.jsxExpressionContainer(types.arrowFunctionExpression([], generateNode(error, params, options)[0])))); | ||
} | ||
if (initialData && initialData.content.referenceType === 'prop') { | ||
cmsNode.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('initialData'), types.jsxExpressionContainer(types.memberExpression(types.identifier(options.dynamicReferencePrefixMap[initialData.content.referenceType]), types.identifier(initialData.content.id))))); | ||
cmsNode.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('persistDataDuringLoading'), types.jsxExpressionContainer(types.booleanLiteral(true)))); | ||
cmsNode.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('key'), types.jsxExpressionContainer(types.identifier('props.page')))); | ||
} | ||
if (Object.keys(resourceParams || {}).length > 0) { | ||
var nodeParams = Object.keys(resourceParams).reduce(function (acc, attrKey) { | ||
var property = resourceParams[attrKey]; | ||
if (property.type === 'static') { | ||
acc.push(types.objectProperty(types.stringLiteral(attrKey), (0, ast_utils_1.resolveObjectValue)(property))); | ||
} | ||
if (property.type === 'expr') { | ||
var expression = __1.ASTUtils.getExpressionFromUIDLExpressionNode(property); | ||
acc.push(types.objectProperty(types.stringLiteral(attrKey), expression)); | ||
} | ||
return acc; | ||
}, []); | ||
cmsNode.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('params'), types.jsxExpressionContainer(types.objectExpression(nodeParams)))); | ||
} | ||
params.nodesLookup[key] = cmsNode; | ||
return [cmsNode]; | ||
}; | ||
var generateRepeatNode = function (node, params, options) { | ||
var _a = node.content, repeatContent = _a.node, dataSource = _a.dataSource, meta = _a.meta; | ||
var contentASTs = generateNode(repeatContent, params, options); | ||
var contentAST = generateElementNode(repeatContent, params, options); | ||
var _b = teleport_shared_1.UIDLUtils.getRepeatIteratorNameAndKey(meta), iteratorName = _b.iteratorName, iteratorKey = _b.iteratorKey; | ||
var localIteratorPrefix = options.dynamicReferencePrefixMap.local; | ||
contentASTs.forEach(function (contentAST) { | ||
(0, ast_utils_1.addDynamicAttributeToJSXTag)(contentAST, 'key', iteratorKey, localIteratorPrefix); | ||
}); | ||
(0, ast_utils_1.addDynamicAttributeToJSXTag)(contentAST, 'key', iteratorKey, localIteratorPrefix); | ||
var source = (0, utils_1.getRepeatSourceIdentifier)(dataSource, options); | ||
@@ -239,7 +170,5 @@ var arrowFunctionArguments = [types.identifier(iteratorName)]; | ||
} | ||
return contentASTs.map(function (contentAST) { | ||
return types.jsxExpressionContainer(types.callExpression(types.memberExpression(source, types.identifier('map')), [ | ||
types.arrowFunctionExpression(arrowFunctionArguments, contentAST), | ||
])); | ||
}); | ||
return types.jsxExpressionContainer(types.callExpression(types.memberExpression(source, types.identifier('map')), [ | ||
types.arrowFunctionExpression(arrowFunctionArguments, contentAST), | ||
])); | ||
}; | ||
@@ -249,19 +178,8 @@ var generateConditionalNode = function (node, params, options) { | ||
var conditionIdentifier = (0, utils_1.createConditionIdentifier)(reference, params, options); | ||
var subTrees = generateNode(node.content.node, params, options); | ||
var subTree = generateNode(node.content.node, params, options); | ||
var condition = value !== undefined && value !== null | ||
? { conditions: [{ operand: value, operation: '===' }] } | ||
: node.content.condition; | ||
return subTrees.map(function (subTree) { | ||
return (0, utils_1.createConditionalJSXExpression)(subTree, condition, conditionIdentifier); | ||
}); | ||
return (0, utils_1.createConditionalJSXExpression)(subTree, condition, conditionIdentifier); | ||
}; | ||
var generateCMSListRepeaterNode = function (node, params, options) { | ||
var repeaterNode = __1.ASTBuilders.createJSXTag('Repeater', [], true); | ||
repeaterNode.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('items'), types.jsxExpressionContainer(types.identifier('params')))); | ||
repeaterNode.openingElement.attributes.push(types.jsxAttribute(types.jSXIdentifier('renderItem'), types.jsxExpressionContainer(types.arrowFunctionExpression([types.identifier(node.content.renderPropIdentifier)], generateNode(node.content.nodes.list, params, options)[0])))); | ||
if ('empty' in node.content.nodes) { | ||
repeaterNode.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('renderEmpty'), types.jsxExpressionContainer(types.arrowFunctionExpression([], generateNode(node.content.nodes.empty, params, options)[0])))); | ||
} | ||
return [repeaterNode]; | ||
}; | ||
var generatePropsSlotNode = function (node, params, options) { | ||
@@ -279,13 +197,11 @@ // React/Preact do not have native slot nodes and implement this differently through the props.children syntax. | ||
if (node.content.fallback) { | ||
var fallbackContents = generateNode(node.content.fallback, params, options); | ||
var fallbackContent = generateNode(node.content.fallback, params, options); | ||
// only static dynamic or element are allowed here | ||
return fallbackContents.map(function (fallbackContent) { | ||
var fallbackNode = typeof fallbackContent === 'string' | ||
? types.stringLiteral(fallbackContent) | ||
: fallbackContent; | ||
// props.children with fallback | ||
return types.jsxExpressionContainer(types.logicalExpression('||', childrenExpression, fallbackNode)); | ||
}); | ||
var fallbackNode = typeof fallbackContent === 'string' | ||
? types.stringLiteral(fallbackContent) | ||
: fallbackContent; | ||
// props.children with fallback | ||
return types.jsxExpressionContainer(types.logicalExpression('||', childrenExpression, fallbackNode)); | ||
} | ||
return [types.jsxExpressionContainer(childrenExpression)]; | ||
return types.jsxExpressionContainer(childrenExpression); | ||
}; | ||
@@ -298,14 +214,12 @@ var generateNativeSlotNode = function (node, params, options) { | ||
if (node.content.fallback) { | ||
var fallbackContents = generateNode(node.content.fallback, params, options); | ||
fallbackContents.forEach(function (fallbackContent) { | ||
if (typeof fallbackContent === 'string') { | ||
(0, ast_utils_1.addChildJSXText)(slotNode, fallbackContent); | ||
} | ||
else if (fallbackContent.type === 'MemberExpression') { | ||
(0, ast_utils_1.addChildJSXTag)(slotNode, types.jsxExpressionContainer(fallbackContent)); | ||
} | ||
else { | ||
(0, ast_utils_1.addChildJSXTag)(slotNode, fallbackContent); | ||
} | ||
}); | ||
var fallbackContent = generateNode(node.content.fallback, params, options); | ||
if (typeof fallbackContent === 'string') { | ||
(0, ast_utils_1.addChildJSXText)(slotNode, fallbackContent); | ||
} | ||
else if (fallbackContent.type === 'MemberExpression') { | ||
(0, ast_utils_1.addChildJSXTag)(slotNode, types.jsxExpressionContainer(fallbackContent)); | ||
} | ||
else { | ||
(0, ast_utils_1.addChildJSXTag)(slotNode, fallbackContent); | ||
} | ||
} | ||
@@ -312,0 +226,0 @@ return slotNode; |
import * as types from '@babel/types'; | ||
import { UIDLPropDefinition, UIDLDependency, UIDLStateDefinition, ProjectResource } from '@teleporthq/teleport-types'; | ||
import { UIDLPropDefinition, UIDLDependency, UIDLStateDefinition } from '@teleporthq/teleport-types'; | ||
export interface JSXGenerationParams { | ||
@@ -9,3 +9,2 @@ propDefinitions: Record<string, UIDLPropDefinition>; | ||
windowImports: Record<string, types.ExpressionStatement>; | ||
projectResources?: Record<string, ProjectResource>; | ||
} | ||
@@ -24,6 +23,6 @@ export interface JSXGenerationOptions { | ||
} | ||
export declare type NodeToJSX<NodeType, ReturnType> = (node: NodeType, params: JSXGenerationParams, options?: JSXGenerationOptions) => ReturnType; | ||
export declare type JSXASTReturnType = string | types.JSXExpressionContainer | types.JSXElement | types.LogicalExpression | types.Identifier | types.MemberExpression; | ||
export declare type BinaryOperator = '===' | '+' | '-' | '/' | '%' | '*' | '**' | '&' | '|' | '>>' | '>>>' | '<<' | '^' | '==' | '!=' | '!==' | 'in' | 'instanceof' | '>' | '<' | '>=' | '<='; | ||
export declare type UnaryOperation = '+' | '-' | 'void' | 'throw' | 'delete' | '!' | '~' | 'typeof'; | ||
export type NodeToJSX<NodeType, ReturnType> = (node: NodeType, params: JSXGenerationParams, options?: JSXGenerationOptions) => ReturnType; | ||
export type JSXASTReturnType = string | types.JSXExpressionContainer | types.JSXElement | types.LogicalExpression | types.Identifier | types.MemberExpression; | ||
export type BinaryOperator = '===' | '+' | '-' | '/' | '%' | '*' | '**' | '&' | '|' | '>>' | '>>>' | '<<' | '^' | '==' | '!=' | '!==' | 'in' | 'instanceof' | '>' | '<' | '>=' | '<='; | ||
export type UnaryOperation = '+' | '-' | 'void' | 'throw' | 'delete' | '!' | '~' | 'typeof'; | ||
export interface ConditionalIdentifier { | ||
@@ -30,0 +29,0 @@ key: string; |
@@ -106,5 +106,3 @@ "use strict"; | ||
case 'hooks': | ||
return t.expressionStatement(t.callExpression(t.identifier(teleport_shared_1.StringUtils.createStateStoringFunction(stateKey)), [ | ||
newStateValue, | ||
])); | ||
return t.expressionStatement(t.callExpression(t.identifier("set".concat(teleport_shared_1.StringUtils.capitalize(stateKey))), [newStateValue])); | ||
case 'function': | ||
@@ -121,15 +119,11 @@ return t.expressionStatement(t.callExpression(t.identifier('this.setState'), [ | ||
if (t === void 0) { t = types; } | ||
var identifierContent = identifier.content; | ||
var referenceType = identifierContent.referenceType, id = identifierContent.id; | ||
if (referenceType === 'attr' || referenceType === 'children' || referenceType === 'token') { | ||
throw new Error("Dynamic reference type \"".concat(referenceType, "\" is not supported yet")); | ||
} | ||
var prefix = options.dynamicReferencePrefixMap[referenceType] || ''; | ||
var refType = identifier.content.referenceType; | ||
var prefix = options.dynamicReferencePrefixMap[refType] || ''; | ||
return prefix === '' | ||
? t.identifier(id) | ||
: t.memberExpression(t.identifier(prefix), t.identifier(id)); | ||
? t.identifier(identifier.content.id) | ||
: t.memberExpression(t.identifier(prefix), t.identifier(identifier.content.id)); | ||
}; | ||
exports.createDynamicValueExpression = createDynamicValueExpression; | ||
// Prepares an identifier (from props or state or an expr) to be used as a conditional rendering identifier | ||
// Assumes the type from the corresponding props/state definitions if not expr. Expressions are expected to have a boolean return here | ||
// Prepares an identifier (from props or state) to be used as a conditional rendering identifier | ||
// Assumes the type from the corresponding props/state definitions | ||
var createConditionIdentifier = function (dynamicReference, params, options) { | ||
@@ -152,7 +146,2 @@ var _a = dynamicReference.content, id = _a.id, referenceType = _a.referenceType; | ||
}; | ||
case 'expr': | ||
return { | ||
key: id, | ||
type: 'boolean', | ||
}; | ||
default: | ||
@@ -159,0 +148,0 @@ throw new Error("createConditionIdentifier encountered an invalid reference type: ".concat(JSON.stringify(dynamicReference, null, 2))); |
import * as types from '@babel/types'; | ||
import ParsedASTNode from './parsed-ast'; | ||
import { UIDLStateDefinition, UIDLPropDefinition, UIDLRawValue, UIDLStaticValue, UIDLResourceItem, UIDLPropValue, UIDLExpressionValue, UIDLStateValue } from '@teleporthq/teleport-types'; | ||
import { UIDLStateDefinition, UIDLPropDefinition, UIDLRawValue } from '@teleporthq/teleport-types'; | ||
/** | ||
@@ -12,9 +12,2 @@ * Adds a class definition string to an existing string of classes | ||
export declare const addDynamicAttributeToJSXTag: (jsxASTNode: types.JSXElement, name: string, value: string, prefix?: string, t?: typeof types) => void; | ||
/** | ||
* Make code expressions happen in AST | ||
* Replace variables that are found in AST with | ||
* the corresponding value from the contexts for now | ||
* and in the future with other sources. | ||
*/ | ||
export declare const addDynamicExpressionAttributeToJSXTag: (jsxASTNode: types.JSXElement, dynamicRef: UIDLExpressionValue, attrKey: string, t?: typeof types) => void; | ||
export declare const addMultipleDynamicAttributesToJSXTag: (jsxASTNode: types.JSXElement, name: string, attrValues?: Array<types.MemberExpression | types.Identifier>, t?: typeof types) => void; | ||
@@ -31,3 +24,3 @@ export declare const stringAsTemplateLiteral: (str: string, t?: typeof types) => types.TemplateLiteral; | ||
}, t?: typeof types) => types.ObjectExpression; | ||
declare type ExpressionLiteral = types.StringLiteral | types.BooleanLiteral | types.NumericLiteral | types.Identifier | types.ArrayExpression | types.ObjectExpression | types.NullLiteral; | ||
type ExpressionLiteral = types.StringLiteral | types.BooleanLiteral | types.NumericLiteral | types.Identifier | types.ArrayExpression | types.ObjectExpression | types.NullLiteral; | ||
export declare const convertValueToLiteral: (value: any, explicitType?: string, t?: typeof types) => ExpressionLiteral; | ||
@@ -47,9 +40,3 @@ export declare const addPropertyToASTObject: (obj: types.ObjectExpression, key: string, value: any, t?: typeof types) => void; | ||
export declare const wrapObjectPropertiesWithExpression: (properties: types.ObjectProperty[]) => types.ObjectExpression; | ||
export declare const generateRemoteResourceASTs: (resource: UIDLResourceItem) => types.VariableDeclaration[]; | ||
export declare const generateMemberExpressionASTFromBase: (base: types.MemberExpression | types.Identifier, path: string[]) => types.MemberExpression; | ||
export declare const generateMemberExpressionASTFromPath: (path: Array<string | number>) => types.MemberExpression | types.Identifier; | ||
export declare const generateURLParamsAST: (urlParams: Record<string, UIDLStaticValue | UIDLStateValue | UIDLPropValue>) => types.TemplateLiteral | null; | ||
export declare const resolveObjectValue: (prop: UIDLStaticValue | UIDLPropValue | UIDLExpressionValue) => types.BooleanLiteral | types.Identifier | types.NumericLiteral | types.ObjectExpression | types.StringLiteral; | ||
export declare const getExpressionFromUIDLExpressionNode: (node: UIDLExpressionValue) => types.Expression; | ||
export {}; | ||
//# sourceMappingURL=ast-utils.d.ts.map |
@@ -38,8 +38,6 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getExpressionFromUIDLExpressionNode = exports.resolveObjectValue = exports.generateURLParamsAST = exports.generateMemberExpressionASTFromPath = exports.generateMemberExpressionASTFromBase = exports.generateRemoteResourceASTs = exports.wrapObjectPropertiesWithExpression = exports.generateDynamicWindowImport = exports.createStateHookAST = exports.createReturnExpressionSyntax = exports.createPureComponent = exports.createClassComponent = exports.removeAttributeByName = exports.findAttributeByName = exports.getTSAnnotationForType = exports.addPropertyToASTObject = exports.convertValueToLiteral = exports.objectToObjectExpression = exports.renameJSXTag = exports.addSpreadAttributeToJSXTag = exports.addChildJSXText = exports.addChildJSXTag = exports.addRawAttributeToJSXTag = exports.addAttributeToJSXTag = exports.stringAsTemplateLiteral = exports.addMultipleDynamicAttributesToJSXTag = exports.addDynamicExpressionAttributeToJSXTag = exports.addDynamicAttributeToJSXTag = exports.addClassStringOnJSXTag = void 0; | ||
exports.wrapObjectPropertiesWithExpression = exports.generateDynamicWindowImport = exports.createStateHookAST = exports.createReturnExpressionSyntax = exports.createPureComponent = exports.createClassComponent = exports.removeAttributeByName = exports.findAttributeByName = exports.getTSAnnotationForType = exports.addPropertyToASTObject = exports.convertValueToLiteral = exports.objectToObjectExpression = exports.renameJSXTag = exports.addSpreadAttributeToJSXTag = exports.addChildJSXText = exports.addChildJSXTag = exports.addRawAttributeToJSXTag = exports.addAttributeToJSXTag = exports.stringAsTemplateLiteral = exports.addMultipleDynamicAttributesToJSXTag = exports.addDynamicAttributeToJSXTag = exports.addClassStringOnJSXTag = void 0; | ||
var types = __importStar(require("@babel/types")); | ||
var core_1 = require("@babel/core"); | ||
var parsed_ast_1 = __importDefault(require("./parsed-ast")); | ||
var teleport_shared_1 = require("@teleporthq/teleport-shared"); | ||
var __1 = require(".."); | ||
/** | ||
@@ -111,29 +109,2 @@ * Adds a class definition string to an existing string of classes | ||
exports.addDynamicAttributeToJSXTag = addDynamicAttributeToJSXTag; | ||
/** | ||
* Make code expressions happen in AST | ||
* Replace variables that are found in AST with | ||
* the corresponding value from the contexts for now | ||
* and in the future with other sources. | ||
*/ | ||
var addDynamicExpressionAttributeToJSXTag = function (jsxASTNode, dynamicRef, attrKey, t) { | ||
if (t === void 0) { t = types; } | ||
var dynamicContent = dynamicRef.content; | ||
if (dynamicRef.type !== 'expr') { | ||
throw new Error("This method only works with dynamic nodes that have code expressions"); | ||
} | ||
var code = dynamicContent; | ||
var options = { | ||
sourceType: 'module', | ||
}; | ||
var ast = (0, core_1.parse)(code, options); | ||
if (!('program' in ast)) { | ||
throw new Error("The AST does not have a program node in the expression inside addDynamicExpressionAttributeToJSXTag"); | ||
} | ||
var theStatementOnlyWihtoutTheProgram = ast.program.body[0]; | ||
if (theStatementOnlyWihtoutTheProgram.type !== 'ExpressionStatement') { | ||
throw new Error("Expr dynamic attribute only support expressions statements at the moment."); | ||
} | ||
jsxASTNode.openingElement.attributes.push(t.jsxAttribute(t.jsxIdentifier(attrKey), t.jsxExpressionContainer(theStatementOnlyWihtoutTheProgram.expression))); | ||
}; | ||
exports.addDynamicExpressionAttributeToJSXTag = addDynamicExpressionAttributeToJSXTag; | ||
/* | ||
@@ -389,4 +360,4 @@ Use, when we need to add a mix of dynamic and static values to | ||
t.variableDeclarator(t.arrayPattern([ | ||
t.identifier(teleport_shared_1.StringUtils.createStateOrPropStoringValue(stateKey)), | ||
t.identifier(teleport_shared_1.StringUtils.createStateStoringFunction(stateKey)), | ||
t.identifier(stateKey), | ||
t.identifier("set".concat(teleport_shared_1.StringUtils.capitalize(stateKey))), | ||
]), t.callExpression(t.identifier('useState'), [defaultValueArgument])), | ||
@@ -408,266 +379,2 @@ ]); | ||
exports.wrapObjectPropertiesWithExpression = wrapObjectPropertiesWithExpression; | ||
var generateRemoteResourceASTs = function (resource) { | ||
var _a, _b; | ||
var fetchUrl = computeFetchUrl(resource); | ||
var authHeaderAST = computeAuthorizationHeaderAST(resource === null || resource === void 0 ? void 0 : resource.headers); | ||
var headersASTs = generateRESTHeadersAST(resource === null || resource === void 0 ? void 0 : resource.headers); | ||
var queryParams = (0, exports.generateURLParamsAST)(resource === null || resource === void 0 ? void 0 : resource.params); | ||
var fetchUrlQuasis = fetchUrl.quasis; | ||
var queryParamsQuasis = (queryParams === null || queryParams === void 0 ? void 0 : queryParams.quasis) || [types.templateElement({ raw: '', cooked: '' })]; | ||
if ((queryParams === null || queryParams === void 0 ? void 0 : queryParams.expressions.length) > 0) { | ||
fetchUrlQuasis[fetchUrlQuasis.length - 1].value.raw = | ||
fetchUrlQuasis[fetchUrlQuasis.length - 1].value.raw + '?'; | ||
fetchUrlQuasis[fetchUrlQuasis.length - 1].value.cooked = | ||
fetchUrlQuasis[fetchUrlQuasis.length - 1].value.cooked + '?'; | ||
queryParamsQuasis.pop(); | ||
} | ||
var paramsDeclerations = Object.keys((resource === null || resource === void 0 ? void 0 : resource.params) || {}).reduce(function (acc, item) { | ||
var prop = resource.params[item]; | ||
if (prop.type === 'static') { | ||
acc.push(types.objectProperty(types.stringLiteral(item), __1.ASTUtils.resolveObjectValue(prop))); | ||
} | ||
if (prop.type === 'dynamic') { | ||
acc.push(types.spreadElement(types.logicalExpression('&&', types.memberExpression(types.identifier('params'), types.stringLiteral(prop.content.id), true, false), types.objectExpression([ | ||
types.objectProperty(types.stringLiteral(item), types.memberExpression(types.identifier('params'), types.stringLiteral(prop.content.id), true, false)), | ||
])))); | ||
} | ||
return acc; | ||
}, []); | ||
var paramsAST = types.variableDeclaration('const', [ | ||
types.variableDeclarator(types.identifier('urlParams'), types.objectExpression(paramsDeclerations)), | ||
]); | ||
var url = (queryParams === null || queryParams === void 0 ? void 0 : queryParams.quasis) | ||
? types.templateLiteral(__spreadArray(__spreadArray([], fetchUrlQuasis, true), queryParamsQuasis, true), __spreadArray([], fetchUrl.expressions.concat(queryParams.expressions), true)) | ||
: fetchUrl; | ||
var fetchAST = types.variableDeclaration('const', [ | ||
types.variableDeclarator(types.identifier('data'), types.awaitExpression(types.callExpression(types.identifier('fetch'), [ | ||
url, | ||
types.objectExpression([ | ||
types.objectProperty(types.identifier('method'), types.stringLiteral(resource.method)), | ||
types.objectProperty(types.identifier('headers'), types.objectExpression(__spreadArray(__spreadArray([], headersASTs, true), [authHeaderAST], false))), | ||
]), | ||
]))), | ||
]); | ||
var responseType = (_b = (_a = resource === null || resource === void 0 ? void 0 : resource.response) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : 'json'; | ||
var responseJSONAST; | ||
/** | ||
* Responce types can be of json, text and we might be reading just headers | ||
* So, with the response type of the resource. We are returning either | ||
* - data.json() | ||
* - data.text() | ||
* - data.headers | ||
* back to the caller, from the fetch response. | ||
*/ | ||
switch (responseType) { | ||
case 'json': | ||
responseJSONAST = types.variableDeclaration('const', [ | ||
types.variableDeclarator(types.identifier('response'), types.awaitExpression(types.callExpression(types.memberExpression(types.identifier('data'), types.identifier('json'), false), []))), | ||
]); | ||
break; | ||
case 'text': { | ||
responseJSONAST = types.variableDeclaration('const', [ | ||
types.variableDeclarator(types.identifier('response'), types.awaitExpression(types.callExpression(types.memberExpression(types.identifier('data'), types.identifier('text'), false), []))), | ||
]); | ||
break; | ||
} | ||
case 'headers': { | ||
responseJSONAST = types.variableDeclaration('const', [ | ||
types.variableDeclarator(types.identifier('response'), types.memberExpression(types.identifier('data'), types.identifier('headers'))), | ||
]); | ||
break; | ||
} | ||
case 'none': { | ||
responseJSONAST = types.variableDeclaration('const', [ | ||
types.variableDeclarator(types.identifier('response'), types.identifier('data')), | ||
]); | ||
break; | ||
} | ||
default: { | ||
responseJSONAST = types.variableDeclaration('const', [ | ||
types.variableDeclarator(types.identifier('response'), types.identifier('data')), | ||
]); | ||
} | ||
} | ||
return [paramsAST, fetchAST, responseJSONAST]; | ||
}; | ||
exports.generateRemoteResourceASTs = generateRemoteResourceASTs; | ||
var generateRESTHeadersAST = function (headers) { | ||
return Object.keys(headers) | ||
.filter(function (header) { return header !== 'authToken'; }) | ||
.map(function (header) { | ||
return types.objectProperty(types.stringLiteral(header), types.stringLiteral(String(headers[header].content))); | ||
}); | ||
}; | ||
var generateMemberExpressionASTFromBase = function (base, path) { | ||
if (path.length === 1) { | ||
return types.memberExpression(base, types.identifier(path[0]), false); | ||
} | ||
var pathClone = __spreadArray([], path, true); | ||
pathClone.pop(); | ||
return types.memberExpression((0, exports.generateMemberExpressionASTFromBase)(base, pathClone), types.identifier(path[path.length - 1]), false); | ||
}; | ||
exports.generateMemberExpressionASTFromBase = generateMemberExpressionASTFromBase; | ||
var generateMemberExpressionASTFromPath = function (path) { | ||
var pathClone = __spreadArray([], path, true); | ||
if (path.length === 1) { | ||
return types.identifier(path[0].toString()); | ||
} | ||
pathClone.pop(); | ||
var currentPath = path[path.length - 1]; | ||
if (typeof currentPath === 'number') { | ||
return types.memberExpression((0, exports.generateMemberExpressionASTFromPath)(pathClone), types.numericLiteral(currentPath), true); | ||
} | ||
var containsSpecial = currentPath.indexOf('.') !== -1 || currentPath.indexOf('-') !== -1; | ||
return types.memberExpression((0, exports.generateMemberExpressionASTFromPath)(pathClone), containsSpecial ? types.stringLiteral(currentPath) : types.identifier(currentPath), containsSpecial); | ||
}; | ||
exports.generateMemberExpressionASTFromPath = generateMemberExpressionASTFromPath; | ||
var generateURLParamsAST = function (urlParams) { | ||
if (!urlParams) { | ||
return null; | ||
} | ||
var queryString = {}; | ||
Object.keys(urlParams).forEach(function (key) { | ||
resolveDynamicValuesFromUrlParams(urlParams[key], queryString, key); | ||
}); | ||
return types.templateLiteral([ | ||
types.templateElement({ raw: '', cooked: '' }, false), | ||
types.templateElement({ raw: '', cooked: '' }, true), | ||
], [types.newExpression(types.identifier('URLSearchParams'), [types.identifier('urlParams')])]); | ||
}; | ||
exports.generateURLParamsAST = generateURLParamsAST; | ||
var resolveDynamicValuesFromUrlParams = function (field, query, prefix) { | ||
if (prefix === void 0) { prefix = null; } | ||
if (field.type === 'dynamic' || field.type === 'static') { | ||
query[prefix] = resolveUrlParamsValue(field); | ||
return; | ||
} | ||
}; | ||
var resolveUrlParamsValue = function (urlParam) { | ||
if (urlParam.type === 'static') { | ||
return types.stringLiteral("".concat(urlParam.content)); | ||
} | ||
if (urlParam.content.referenceType !== 'prop' && urlParam.content.referenceType !== 'state') { | ||
throw new Error('Only prop and state references are supported for url params'); | ||
} | ||
var paramPath = __spreadArray(__spreadArray([], (urlParam.content.referenceType === 'prop' ? ['params'] : ['']), true), [ | ||
urlParam.content.id, | ||
], false); | ||
var templateLiteralElements = paramPath | ||
.map(function (_, index) { | ||
var isTail = index === paramPath.length - 1; | ||
return types.templateElement({ | ||
cooked: '', | ||
raw: '', | ||
}, isTail); | ||
}) | ||
.filter(function (el) { return el; }); | ||
return types.templateLiteral(templateLiteralElements, [ | ||
(0, exports.generateMemberExpressionASTFromPath)(paramPath), | ||
]); | ||
}; | ||
var computeAuthorizationHeaderAST = function (headers) { | ||
var _a; | ||
var authToken = resolveResourceValue(headers.authToken); | ||
if (!authToken) { | ||
return null; | ||
} | ||
var authTokenType = (_a = headers.authToken) === null || _a === void 0 ? void 0 : _a.type; | ||
return types.objectProperty(types.identifier('Authorization'), types.templateLiteral(__spreadArray([ | ||
types.templateElement({ | ||
cooked: authTokenType === 'static' ? "Bearer ".concat(authToken) : 'Bearer ', | ||
raw: authTokenType === 'static' ? "Bearer ".concat(authToken) : 'Bearer ', | ||
}, false) | ||
], (authTokenType === 'static' | ||
? [] | ||
: [ | ||
types.templateElement({ | ||
cooked: '', | ||
raw: '', | ||
}, true), | ||
]), true), __spreadArray([], (authTokenType === 'static' ? [] : [types.identifier(String(authToken))]), true)), false, false); | ||
}; | ||
var computeFetchUrl = function (resource) { | ||
var _a, _b; | ||
var path = resource.path; | ||
var fetchBaseUrl = resolveResourceValue(path.baseUrl); | ||
var resourceRoute = resolveResourceValue(path.route); | ||
var baseUrlType = (_a = path.baseUrl) === null || _a === void 0 ? void 0 : _a.type; | ||
var routeType = (_b = path.route) === null || _b === void 0 ? void 0 : _b.type; | ||
if (baseUrlType === 'static' && routeType === 'static') { | ||
var stringsToJoin = [fetchBaseUrl, resourceRoute].filter(function (item) { return item; }).join('/'); | ||
return types.templateLiteral([types.templateElement({ cooked: "".concat(stringsToJoin), raw: "".concat(stringsToJoin) }, true)], []); | ||
} | ||
if (!routeType) { | ||
return baseUrlType === 'static' | ||
? types.templateLiteral([types.templateElement({ cooked: "".concat(fetchBaseUrl), raw: "".concat(fetchBaseUrl) }, true)], []) | ||
: types.templateLiteral([ | ||
types.templateElement({ | ||
cooked: '', | ||
raw: '', | ||
}, false), | ||
types.templateElement({ | ||
cooked: '', | ||
raw: '', | ||
}, true), | ||
], [types.identifier(String(fetchBaseUrl))]); | ||
} | ||
return types.templateLiteral(__spreadArray([ | ||
types.templateElement({ | ||
cooked: '', | ||
raw: '', | ||
}, false), | ||
types.templateElement({ | ||
cooked: routeType === 'static' ? "/".concat(resourceRoute) : '/', | ||
raw: routeType === 'static' ? "/".concat(resourceRoute) : '/', | ||
}, false) | ||
], (routeType === 'static' | ||
? [] | ||
: [ | ||
types.templateElement({ | ||
cooked: '', | ||
raw: '', | ||
}, false), | ||
]), true), __spreadArray([ | ||
types.identifier(String(fetchBaseUrl)) | ||
], (routeType === 'static' ? [] : [types.identifier(String(resourceRoute))]), true)); | ||
}; | ||
var resolveResourceValue = function (value) { | ||
if (!value) { | ||
return ''; | ||
} | ||
if (value.type === 'static') { | ||
return value.content; | ||
} | ||
return "process.env.".concat(value.content); | ||
}; | ||
var resolveObjectValue = function (prop) { | ||
if (prop.type === 'expr') { | ||
return types.identifier(prop.content); | ||
} | ||
var value = typeof prop.content === 'string' | ||
? types.stringLiteral(prop.content) | ||
: typeof prop.content === 'boolean' | ||
? types.booleanLiteral(prop.content) | ||
: typeof prop.content === 'number' | ||
? types.numericLiteral(prop.content) | ||
: typeof prop.content === 'object' | ||
? (0, exports.objectToObjectExpression)(prop.content) | ||
: types.identifier(String(prop.content)); | ||
return value; | ||
}; | ||
exports.resolveObjectValue = resolveObjectValue; | ||
var getExpressionFromUIDLExpressionNode = function (node) { | ||
var ast = (0, core_1.parse)(node.content, { | ||
sourceType: 'module', | ||
}); | ||
if (!('program' in ast)) { | ||
throw new Error("The AST does not have a program node in the expression inside addDynamicExpressionAttributeToJSXTag"); | ||
} | ||
var theStatementOnlyWihtoutTheProgram = ast.program.body[0]; | ||
if (theStatementOnlyWihtoutTheProgram.type !== 'ExpressionStatement') { | ||
throw new Error("Expr dynamic attribute only support expressions statements at the moment."); | ||
} | ||
return theStatementOnlyWihtoutTheProgram.expression; | ||
}; | ||
exports.getExpressionFromUIDLExpressionNode = getExpressionFromUIDLExpressionNode; | ||
//# sourceMappingURL=ast-utils.js.map |
@@ -11,3 +11,3 @@ import * as types from '@babel/types'; | ||
export declare const createGenericImportStatement: (path: string, imports: ImportIdentifier[], t?: typeof types) => types.ImportDeclaration; | ||
declare type JSXChild = types.JSXText | types.JSXExpressionContainer | types.JSXSpreadChild | types.JSXElement | types.JSXFragment; | ||
type JSXChild = types.JSXText | types.JSXExpressionContainer | types.JSXSpreadChild | types.JSXElement | types.JSXFragment; | ||
export declare const createJSXTag: (tagName: string, children?: JSXChild[], selfClosing?: boolean, t?: typeof types) => types.JSXElement; | ||
@@ -14,0 +14,0 @@ export declare const createSelfClosingJSXTag: (tagName: string) => types.JSXElement; |
@@ -6,9 +6,10 @@ import * as types from '@babel/types'; | ||
export declare const createCSSClassWithSelector: (key: string, selector: string, styleObject: Record<string, string | number>) => string; | ||
export declare const createCSSClassWithMediaQuery: (mediaOffset: string, styleObject: Record<string, string | number | Record<string, string | number>>) => string; | ||
export declare const createFontDecleration: (styleObject: Record<string, string | number>) => string; | ||
export declare const createCSSClassWithMediaQuery: (mediaOffset: string, styleObject: Record<string, string | number>) => string; | ||
export declare const createDynamicStyleExpression: (styleValue: UIDLDynamicReference, propsPrefix?: string, t?: typeof types) => string | ParsedASTNode; | ||
export declare const generateMediaStyle: (styleMap: Record<string, { | ||
[x: string]: Record<string, string | number | Record<string, string | number>>; | ||
[x: string]: Record<string, string | number>; | ||
}[]>) => string[]; | ||
export declare const generateStylesFromStyleSetDefinitions: (styleSetDefinitions: Record<string, UIDLStyleSetDefinition>, cssMap: string[], mediaStylesMap: Record<string, { | ||
[x: string]: Record<string, string | number | Record<string, string | number>>; | ||
[x: string]: Record<string, string | number>; | ||
}[]>, className: (val: string) => string) => void; | ||
@@ -15,0 +16,0 @@ export declare const setPropValueForCompStyle: (params: { |
@@ -41,2 +41,9 @@ var __assign = (this && this.__assign) || function () { | ||
}; | ||
export var createFontDecleration = function (styleObject) { | ||
return jss | ||
.createStyleSheet({ | ||
'@font-face': styleObject, | ||
}) | ||
.toString(); | ||
}; | ||
export var createCSSClassWithMediaQuery = function (mediaOffset, styleObject) { | ||
@@ -81,15 +88,10 @@ return jss | ||
var content = style.content, _a = style.conditions, conditions = _a === void 0 ? [] : _a, type = style.type; | ||
var name = className(style.className || styleId); | ||
var subselectors = style.subselectors; | ||
var name = className(styleId); | ||
var _b = UIDLUtils.splitDynamicAndStaticStyles(content), staticStyles = _b.staticStyles, tokenStyles = _b.tokenStyles; | ||
var collectedStyles = __assign(__assign({}, getContentOfStyleObject(staticStyles)), getCSSVariablesContentFromTokenStyles(tokenStyles)); | ||
// & is required by jss, otherwise the final result will be empty | ||
var cls = subselectors | ||
? createCSSClassWithSelector(name, "&".concat(subselectors), collectedStyles) | ||
: createCSSClass(name, collectedStyles); | ||
if (type === 'reusable-component-style-map') { | ||
cssMap.unshift(cls); | ||
cssMap.unshift(createCSSClass(name, collectedStyles)); | ||
} | ||
else { | ||
cssMap.push(cls); | ||
cssMap.push(createCSSClass(name, collectedStyles)); | ||
} | ||
@@ -100,11 +102,11 @@ if (conditions.length === 0) { | ||
conditions.forEach(function (styleRef) { | ||
var _a, _b, _c; | ||
var _d = UIDLUtils.splitDynamicAndStaticStyles(styleRef.content), staticValues = _d.staticStyles, tokenValues = _d.tokenStyles; | ||
var _a, _b; | ||
var _c = UIDLUtils.splitDynamicAndStaticStyles(styleRef.content), staticValues = _c.staticStyles, tokenValues = _c.tokenStyles; | ||
var collecedMediaStyles = __assign(__assign({}, getContentOfStyleObject(staticValues)), getCSSVariablesContentFromTokenStyles(tokenValues)); | ||
if (styleRef.type === 'element-state') { | ||
if (type === 'reusable-component-style-map') { | ||
cssMap.unshift(createCSSClassWithSelector(name, "&".concat(subselectors || '', ":").concat(styleRef.meta.state), collecedMediaStyles)); | ||
cssMap.unshift(createCSSClassWithSelector(name, "&:".concat(styleRef.meta.state), collecedMediaStyles)); | ||
} | ||
else { | ||
cssMap.push(createCSSClassWithSelector(name, "&".concat(subselectors || '', ":").concat(styleRef.meta.state), collecedMediaStyles)); | ||
cssMap.push(createCSSClassWithSelector(name, "&:".concat(styleRef.meta.state), collecedMediaStyles)); | ||
} | ||
@@ -117,9 +119,7 @@ } | ||
} | ||
var mediaStyleMap = subselectors | ||
? (_a = {}, _a["&".concat(subselectors)] = collecedMediaStyles, _a) : collecedMediaStyles; | ||
if (type === 'reusable-component-style-map') { | ||
mediaStylesMap[String(maxWidth)].unshift((_b = {}, _b[name] = mediaStyleMap, _b)); | ||
mediaStylesMap[String(maxWidth)].unshift((_a = {}, _a[name] = collecedMediaStyles, _a)); | ||
} | ||
else { | ||
mediaStylesMap[String(maxWidth)].push((_c = {}, _c[name] = mediaStyleMap, _c)); | ||
mediaStylesMap[String(maxWidth)].push((_b = {}, _b[name] = collecedMediaStyles, _b)); | ||
} | ||
@@ -126,0 +126,0 @@ } |
@@ -73,2 +73,8 @@ var __assign = (this && this.__assign) || function () { | ||
switch (node.type) { | ||
case 'inject': | ||
if (node === null || node === void 0 ? void 0 : node.dependency) { | ||
/* tslint:disable:no-string-literal */ | ||
params.dependencies['Script'] = node.dependency; | ||
} | ||
return node.content.toString(); | ||
case 'raw': | ||
@@ -75,0 +81,0 @@ return generateRawHTMLNode(node, params, templateSyntax); |
@@ -21,3 +21,3 @@ import { UIDLDependency, UIDLEventHandlerStatement, UIDLElementNode } from '@teleporthq/teleport-types'; | ||
} | ||
export declare type NodeToHTML<NodeType, ReturnType> = (node: NodeType, params: HTMLTemplateGenerationParams, templateSyntax: HTMLTemplateSyntax) => ReturnType; | ||
export type NodeToHTML<NodeType, ReturnType> = (node: NodeType, params: HTMLTemplateGenerationParams, templateSyntax: HTMLTemplateSyntax) => ReturnType; | ||
//# sourceMappingURL=types.d.ts.map |
@@ -15,10 +15,9 @@ var __assign = (this && this.__assign) || function () { | ||
import { addEventHandlerToTag, createConditionIdentifier, createDynamicValueExpression, createConditionalJSXExpression, getRepeatSourceIdentifier, } from './utils'; | ||
import { addChildJSXText, addChildJSXTag, addAttributeToJSXTag, addDynamicAttributeToJSXTag, addRawAttributeToJSXTag, generateDynamicWindowImport, addDynamicExpressionAttributeToJSXTag, resolveObjectValue, } from '../../utils/ast-utils'; | ||
import { addChildJSXText, addChildJSXTag, addAttributeToJSXTag, addDynamicAttributeToJSXTag, addRawAttributeToJSXTag, generateDynamicWindowImport, } from '../../utils/ast-utils'; | ||
import { createJSXTag, createSelfClosingJSXTag } from '../../builders/ast-builders'; | ||
import { DEFAULT_JSX_OPTIONS } from './constants'; | ||
import { ASTBuilders, ASTUtils } from '../..'; | ||
var generateElementNode = function (node, params, jsxOptions) { | ||
var dependencies = params.dependencies, nodesLookup = params.nodesLookup, _a = params.projectResources, projectResources = _a === void 0 ? {} : _a; | ||
var options = __assign(__assign(__assign({}, DEFAULT_JSX_OPTIONS), jsxOptions), { projectResources: projectResources }); | ||
var _b = node.content, elementType = _b.elementType, selfClosing = _b.selfClosing, children = _b.children, key = _b.key, attrs = _b.attrs, dependency = _b.dependency, events = _b.events; | ||
var options = __assign(__assign({}, DEFAULT_JSX_OPTIONS), jsxOptions); | ||
var dependencies = params.dependencies, nodesLookup = params.nodesLookup; | ||
var _a = node.content, elementType = _a.elementType, selfClosing = _a.selfClosing, children = _a.children, key = _a.key, attrs = _a.attrs, dependency = _a.dependency, events = _a.events; | ||
var originalElementName = elementType || 'component'; | ||
@@ -53,9 +52,5 @@ var tagName = originalElementName; | ||
case 'dynamic': | ||
var referenceType = attributeValue.content.referenceType; | ||
switch (referenceType) { | ||
default: | ||
var prefix = options.dynamicReferencePrefixMap[referenceType]; | ||
addDynamicAttributeToJSXTag(elementTag, attrKey, attributeValue.content.id, prefix); | ||
break; | ||
} | ||
var _a = attributeValue.content, id = _a.id, referenceType = _a.referenceType; | ||
var prefix = options.dynamicReferencePrefixMap[referenceType]; | ||
addDynamicAttributeToJSXTag(elementTag, attrKey, id, prefix); | ||
break; | ||
@@ -70,7 +65,5 @@ case 'import': | ||
case 'static': | ||
addAttributeToJSXTag(elementTag, attrKey, attributeValue.content); | ||
var content = attributeValue.content; | ||
addAttributeToJSXTag(elementTag, attrKey, content); | ||
break; | ||
case 'expr': | ||
addDynamicExpressionAttributeToJSXTag(elementTag, attributeValue, attrKey); | ||
break; | ||
default: | ||
@@ -88,14 +81,12 @@ throw new Error("generateElementNode could not generate code for attribute of type ".concat(JSON.stringify(attributeValue))); | ||
children.forEach(function (child) { | ||
var childTags = generateNode(child, params, options); | ||
childTags.forEach(function (childTag) { | ||
if (typeof childTag === 'string') { | ||
addChildJSXText(elementTag, childTag); | ||
} | ||
else if (childTag.type === 'JSXExpressionContainer' || childTag.type === 'JSXElement') { | ||
addChildJSXTag(elementTag, childTag); | ||
} | ||
else { | ||
addChildJSXTag(elementTag, types.jsxExpressionContainer(childTag)); | ||
} | ||
}); | ||
var childTag = generateNode(child, params, options); | ||
if (typeof childTag === 'string') { | ||
addChildJSXText(elementTag, childTag); | ||
} | ||
else if (childTag.type === 'JSXExpressionContainer' || childTag.type === 'JSXElement') { | ||
addChildJSXTag(elementTag, childTag); | ||
} | ||
else { | ||
addChildJSXTag(elementTag, types.jsxExpressionContainer(childTag)); | ||
} | ||
}); | ||
@@ -109,19 +100,18 @@ } | ||
switch (node.type) { | ||
case 'expr': | ||
return [generateExpressionNode(node, params, options)]; | ||
case 'inject': | ||
if (node === null || node === void 0 ? void 0 : node.dependency) { | ||
/* tslint:disable:no-string-literal */ | ||
params.dependencies['Script'] = node.dependency; | ||
} | ||
return node.content.toString(); | ||
case 'raw': | ||
return [ | ||
options.domHTMLInjection | ||
? options.domHTMLInjection(node.content.toString()) | ||
: node.content.toString(), | ||
]; | ||
return options.domHTMLInjection | ||
? options.domHTMLInjection(node.content.toString()) | ||
: node.content.toString(); | ||
case 'static': | ||
return [StringUtils.encode(node.content.toString())]; | ||
return StringUtils.encode(node.content.toString()); | ||
case 'dynamic': | ||
return [createDynamicValueExpression(node, options, undefined)]; | ||
case 'cms-item': | ||
case 'cms-list': | ||
return generateCMSNode(node, params, options); | ||
return createDynamicValueExpression(node, options); | ||
case 'element': | ||
return [generateElementNode(node, params, options)]; | ||
return generateElementNode(node, params, options); | ||
case 'repeat': | ||
@@ -131,7 +121,5 @@ return generateRepeatNode(node, params, options); | ||
return generateConditionalNode(node, params, options); | ||
case 'cms-list-repeater': | ||
return generateCMSListRepeaterNode(node, params, options); | ||
case 'slot': | ||
if (options.slotHandling === 'native') { | ||
return [generateNativeSlotNode(node, params, options)]; | ||
return generateNativeSlotNode(node, params, options); | ||
} | ||
@@ -145,65 +133,8 @@ else { | ||
}; | ||
var generateExpressionNode = function (node) { | ||
var expression = ASTUtils.getExpressionFromUIDLExpressionNode(node); | ||
return types.jsxExpressionContainer(expression); | ||
}; | ||
var generateCMSNode = function (node, params, options) { | ||
var _a = node.content, initialData = _a.initialData, key = _a.key, renderPropIdentifier = _a.renderPropIdentifier, _b = _a.resource, _c = _b === void 0 ? {} : _b, resourceParams = _c.params, router = _a.router, elementType = _a.elementType, dependency = _a.dependency; | ||
var _d = node.content.nodes, loading = _d.loading, error = _d.error, success = _d.success; | ||
var jsxTag = StringUtils.dashCaseToUpperCamelCase(elementType); | ||
if (router && (options === null || options === void 0 ? void 0 : options.dependencyHandling) === 'import') { | ||
params.dependencies.useRouter = router; | ||
} | ||
if (!success) { | ||
return []; | ||
} | ||
if (dependency && options.dependencyHandling === 'import') { | ||
params.dependencies[elementType] = dependency; | ||
} | ||
var cmsNode = ASTBuilders.createJSXTag(jsxTag, [], true); | ||
if (node.type === 'cms-item') { | ||
cmsNode.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('renderSuccess'), types.jsxExpressionContainer(types.arrowFunctionExpression([types.identifier(renderPropIdentifier)], generateNode(success, params, options)[0])))); | ||
} | ||
if (node.type === 'cms-list') { | ||
cmsNode.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('renderSuccess'), types.jsxExpressionContainer(types.arrowFunctionExpression([types.identifier('params')], generateNode(success, params, options)[0])))); | ||
} | ||
if (dependency && options.dependencyHandling === 'import') { | ||
params.dependencies.Repeater = dependency; | ||
} | ||
if (loading) { | ||
cmsNode.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('renderLoading'), types.jsxExpressionContainer(types.arrowFunctionExpression([], generateNode(loading, params, options)[0])))); | ||
} | ||
if (error) { | ||
cmsNode.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('renderError'), types.jsxExpressionContainer(types.arrowFunctionExpression([], generateNode(error, params, options)[0])))); | ||
} | ||
if (initialData && initialData.content.referenceType === 'prop') { | ||
cmsNode.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('initialData'), types.jsxExpressionContainer(types.memberExpression(types.identifier(options.dynamicReferencePrefixMap[initialData.content.referenceType]), types.identifier(initialData.content.id))))); | ||
cmsNode.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('persistDataDuringLoading'), types.jsxExpressionContainer(types.booleanLiteral(true)))); | ||
cmsNode.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('key'), types.jsxExpressionContainer(types.identifier('props.page')))); | ||
} | ||
if (Object.keys(resourceParams || {}).length > 0) { | ||
var nodeParams = Object.keys(resourceParams).reduce(function (acc, attrKey) { | ||
var property = resourceParams[attrKey]; | ||
if (property.type === 'static') { | ||
acc.push(types.objectProperty(types.stringLiteral(attrKey), resolveObjectValue(property))); | ||
} | ||
if (property.type === 'expr') { | ||
var expression = ASTUtils.getExpressionFromUIDLExpressionNode(property); | ||
acc.push(types.objectProperty(types.stringLiteral(attrKey), expression)); | ||
} | ||
return acc; | ||
}, []); | ||
cmsNode.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('params'), types.jsxExpressionContainer(types.objectExpression(nodeParams)))); | ||
} | ||
params.nodesLookup[key] = cmsNode; | ||
return [cmsNode]; | ||
}; | ||
var generateRepeatNode = function (node, params, options) { | ||
var _a = node.content, repeatContent = _a.node, dataSource = _a.dataSource, meta = _a.meta; | ||
var contentASTs = generateNode(repeatContent, params, options); | ||
var contentAST = generateElementNode(repeatContent, params, options); | ||
var _b = UIDLUtils.getRepeatIteratorNameAndKey(meta), iteratorName = _b.iteratorName, iteratorKey = _b.iteratorKey; | ||
var localIteratorPrefix = options.dynamicReferencePrefixMap.local; | ||
contentASTs.forEach(function (contentAST) { | ||
addDynamicAttributeToJSXTag(contentAST, 'key', iteratorKey, localIteratorPrefix); | ||
}); | ||
addDynamicAttributeToJSXTag(contentAST, 'key', iteratorKey, localIteratorPrefix); | ||
var source = getRepeatSourceIdentifier(dataSource, options); | ||
@@ -214,7 +145,5 @@ var arrowFunctionArguments = [types.identifier(iteratorName)]; | ||
} | ||
return contentASTs.map(function (contentAST) { | ||
return types.jsxExpressionContainer(types.callExpression(types.memberExpression(source, types.identifier('map')), [ | ||
types.arrowFunctionExpression(arrowFunctionArguments, contentAST), | ||
])); | ||
}); | ||
return types.jsxExpressionContainer(types.callExpression(types.memberExpression(source, types.identifier('map')), [ | ||
types.arrowFunctionExpression(arrowFunctionArguments, contentAST), | ||
])); | ||
}; | ||
@@ -224,19 +153,8 @@ var generateConditionalNode = function (node, params, options) { | ||
var conditionIdentifier = createConditionIdentifier(reference, params, options); | ||
var subTrees = generateNode(node.content.node, params, options); | ||
var subTree = generateNode(node.content.node, params, options); | ||
var condition = value !== undefined && value !== null | ||
? { conditions: [{ operand: value, operation: '===' }] } | ||
: node.content.condition; | ||
return subTrees.map(function (subTree) { | ||
return createConditionalJSXExpression(subTree, condition, conditionIdentifier); | ||
}); | ||
return createConditionalJSXExpression(subTree, condition, conditionIdentifier); | ||
}; | ||
var generateCMSListRepeaterNode = function (node, params, options) { | ||
var repeaterNode = ASTBuilders.createJSXTag('Repeater', [], true); | ||
repeaterNode.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('items'), types.jsxExpressionContainer(types.identifier('params')))); | ||
repeaterNode.openingElement.attributes.push(types.jsxAttribute(types.jSXIdentifier('renderItem'), types.jsxExpressionContainer(types.arrowFunctionExpression([types.identifier(node.content.renderPropIdentifier)], generateNode(node.content.nodes.list, params, options)[0])))); | ||
if ('empty' in node.content.nodes) { | ||
repeaterNode.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('renderEmpty'), types.jsxExpressionContainer(types.arrowFunctionExpression([], generateNode(node.content.nodes.empty, params, options)[0])))); | ||
} | ||
return [repeaterNode]; | ||
}; | ||
var generatePropsSlotNode = function (node, params, options) { | ||
@@ -254,13 +172,11 @@ // React/Preact do not have native slot nodes and implement this differently through the props.children syntax. | ||
if (node.content.fallback) { | ||
var fallbackContents = generateNode(node.content.fallback, params, options); | ||
var fallbackContent = generateNode(node.content.fallback, params, options); | ||
// only static dynamic or element are allowed here | ||
return fallbackContents.map(function (fallbackContent) { | ||
var fallbackNode = typeof fallbackContent === 'string' | ||
? types.stringLiteral(fallbackContent) | ||
: fallbackContent; | ||
// props.children with fallback | ||
return types.jsxExpressionContainer(types.logicalExpression('||', childrenExpression, fallbackNode)); | ||
}); | ||
var fallbackNode = typeof fallbackContent === 'string' | ||
? types.stringLiteral(fallbackContent) | ||
: fallbackContent; | ||
// props.children with fallback | ||
return types.jsxExpressionContainer(types.logicalExpression('||', childrenExpression, fallbackNode)); | ||
} | ||
return [types.jsxExpressionContainer(childrenExpression)]; | ||
return types.jsxExpressionContainer(childrenExpression); | ||
}; | ||
@@ -273,14 +189,12 @@ var generateNativeSlotNode = function (node, params, options) { | ||
if (node.content.fallback) { | ||
var fallbackContents = generateNode(node.content.fallback, params, options); | ||
fallbackContents.forEach(function (fallbackContent) { | ||
if (typeof fallbackContent === 'string') { | ||
addChildJSXText(slotNode, fallbackContent); | ||
} | ||
else if (fallbackContent.type === 'MemberExpression') { | ||
addChildJSXTag(slotNode, types.jsxExpressionContainer(fallbackContent)); | ||
} | ||
else { | ||
addChildJSXTag(slotNode, fallbackContent); | ||
} | ||
}); | ||
var fallbackContent = generateNode(node.content.fallback, params, options); | ||
if (typeof fallbackContent === 'string') { | ||
addChildJSXText(slotNode, fallbackContent); | ||
} | ||
else if (fallbackContent.type === 'MemberExpression') { | ||
addChildJSXTag(slotNode, types.jsxExpressionContainer(fallbackContent)); | ||
} | ||
else { | ||
addChildJSXTag(slotNode, fallbackContent); | ||
} | ||
} | ||
@@ -287,0 +201,0 @@ return slotNode; |
import * as types from '@babel/types'; | ||
import { UIDLPropDefinition, UIDLDependency, UIDLStateDefinition, ProjectResource } from '@teleporthq/teleport-types'; | ||
import { UIDLPropDefinition, UIDLDependency, UIDLStateDefinition } from '@teleporthq/teleport-types'; | ||
export interface JSXGenerationParams { | ||
@@ -9,3 +9,2 @@ propDefinitions: Record<string, UIDLPropDefinition>; | ||
windowImports: Record<string, types.ExpressionStatement>; | ||
projectResources?: Record<string, ProjectResource>; | ||
} | ||
@@ -24,6 +23,6 @@ export interface JSXGenerationOptions { | ||
} | ||
export declare type NodeToJSX<NodeType, ReturnType> = (node: NodeType, params: JSXGenerationParams, options?: JSXGenerationOptions) => ReturnType; | ||
export declare type JSXASTReturnType = string | types.JSXExpressionContainer | types.JSXElement | types.LogicalExpression | types.Identifier | types.MemberExpression; | ||
export declare type BinaryOperator = '===' | '+' | '-' | '/' | '%' | '*' | '**' | '&' | '|' | '>>' | '>>>' | '<<' | '^' | '==' | '!=' | '!==' | 'in' | 'instanceof' | '>' | '<' | '>=' | '<='; | ||
export declare type UnaryOperation = '+' | '-' | 'void' | 'throw' | 'delete' | '!' | '~' | 'typeof'; | ||
export type NodeToJSX<NodeType, ReturnType> = (node: NodeType, params: JSXGenerationParams, options?: JSXGenerationOptions) => ReturnType; | ||
export type JSXASTReturnType = string | types.JSXExpressionContainer | types.JSXElement | types.LogicalExpression | types.Identifier | types.MemberExpression; | ||
export type BinaryOperator = '===' | '+' | '-' | '/' | '%' | '*' | '**' | '&' | '|' | '>>' | '>>>' | '<<' | '^' | '==' | '!=' | '!==' | 'in' | 'instanceof' | '>' | '<' | '>=' | '<='; | ||
export type UnaryOperation = '+' | '-' | 'void' | 'throw' | 'delete' | '!' | '~' | 'typeof'; | ||
export interface ConditionalIdentifier { | ||
@@ -30,0 +29,0 @@ key: string; |
@@ -79,5 +79,3 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { | ||
case 'hooks': | ||
return t.expressionStatement(t.callExpression(t.identifier(StringUtils.createStateStoringFunction(stateKey)), [ | ||
newStateValue, | ||
])); | ||
return t.expressionStatement(t.callExpression(t.identifier("set".concat(StringUtils.capitalize(stateKey))), [newStateValue])); | ||
case 'function': | ||
@@ -94,14 +92,10 @@ return t.expressionStatement(t.callExpression(t.identifier('this.setState'), [ | ||
if (t === void 0) { t = types; } | ||
var identifierContent = identifier.content; | ||
var referenceType = identifierContent.referenceType, id = identifierContent.id; | ||
if (referenceType === 'attr' || referenceType === 'children' || referenceType === 'token') { | ||
throw new Error("Dynamic reference type \"".concat(referenceType, "\" is not supported yet")); | ||
} | ||
var prefix = options.dynamicReferencePrefixMap[referenceType] || ''; | ||
var refType = identifier.content.referenceType; | ||
var prefix = options.dynamicReferencePrefixMap[refType] || ''; | ||
return prefix === '' | ||
? t.identifier(id) | ||
: t.memberExpression(t.identifier(prefix), t.identifier(id)); | ||
? t.identifier(identifier.content.id) | ||
: t.memberExpression(t.identifier(prefix), t.identifier(identifier.content.id)); | ||
}; | ||
// Prepares an identifier (from props or state or an expr) to be used as a conditional rendering identifier | ||
// Assumes the type from the corresponding props/state definitions if not expr. Expressions are expected to have a boolean return here | ||
// Prepares an identifier (from props or state) to be used as a conditional rendering identifier | ||
// Assumes the type from the corresponding props/state definitions | ||
export var createConditionIdentifier = function (dynamicReference, params, options) { | ||
@@ -124,7 +118,2 @@ var _a = dynamicReference.content, id = _a.id, referenceType = _a.referenceType; | ||
}; | ||
case 'expr': | ||
return { | ||
key: id, | ||
type: 'boolean', | ||
}; | ||
default: | ||
@@ -131,0 +120,0 @@ throw new Error("createConditionIdentifier encountered an invalid reference type: ".concat(JSON.stringify(dynamicReference, null, 2))); |
import * as types from '@babel/types'; | ||
import ParsedASTNode from './parsed-ast'; | ||
import { UIDLStateDefinition, UIDLPropDefinition, UIDLRawValue, UIDLStaticValue, UIDLResourceItem, UIDLPropValue, UIDLExpressionValue, UIDLStateValue } from '@teleporthq/teleport-types'; | ||
import { UIDLStateDefinition, UIDLPropDefinition, UIDLRawValue } from '@teleporthq/teleport-types'; | ||
/** | ||
@@ -12,9 +12,2 @@ * Adds a class definition string to an existing string of classes | ||
export declare const addDynamicAttributeToJSXTag: (jsxASTNode: types.JSXElement, name: string, value: string, prefix?: string, t?: typeof types) => void; | ||
/** | ||
* Make code expressions happen in AST | ||
* Replace variables that are found in AST with | ||
* the corresponding value from the contexts for now | ||
* and in the future with other sources. | ||
*/ | ||
export declare const addDynamicExpressionAttributeToJSXTag: (jsxASTNode: types.JSXElement, dynamicRef: UIDLExpressionValue, attrKey: string, t?: typeof types) => void; | ||
export declare const addMultipleDynamicAttributesToJSXTag: (jsxASTNode: types.JSXElement, name: string, attrValues?: Array<types.MemberExpression | types.Identifier>, t?: typeof types) => void; | ||
@@ -31,3 +24,3 @@ export declare const stringAsTemplateLiteral: (str: string, t?: typeof types) => types.TemplateLiteral; | ||
}, t?: typeof types) => types.ObjectExpression; | ||
declare type ExpressionLiteral = types.StringLiteral | types.BooleanLiteral | types.NumericLiteral | types.Identifier | types.ArrayExpression | types.ObjectExpression | types.NullLiteral; | ||
type ExpressionLiteral = types.StringLiteral | types.BooleanLiteral | types.NumericLiteral | types.Identifier | types.ArrayExpression | types.ObjectExpression | types.NullLiteral; | ||
export declare const convertValueToLiteral: (value: any, explicitType?: string, t?: typeof types) => ExpressionLiteral; | ||
@@ -47,9 +40,3 @@ export declare const addPropertyToASTObject: (obj: types.ObjectExpression, key: string, value: any, t?: typeof types) => void; | ||
export declare const wrapObjectPropertiesWithExpression: (properties: types.ObjectProperty[]) => types.ObjectExpression; | ||
export declare const generateRemoteResourceASTs: (resource: UIDLResourceItem) => types.VariableDeclaration[]; | ||
export declare const generateMemberExpressionASTFromBase: (base: types.MemberExpression | types.Identifier, path: string[]) => types.MemberExpression; | ||
export declare const generateMemberExpressionASTFromPath: (path: Array<string | number>) => types.MemberExpression | types.Identifier; | ||
export declare const generateURLParamsAST: (urlParams: Record<string, UIDLStaticValue | UIDLStateValue | UIDLPropValue>) => types.TemplateLiteral | null; | ||
export declare const resolveObjectValue: (prop: UIDLStaticValue | UIDLPropValue | UIDLExpressionValue) => types.BooleanLiteral | types.Identifier | types.NumericLiteral | types.ObjectExpression | types.StringLiteral; | ||
export declare const getExpressionFromUIDLExpressionNode: (node: UIDLExpressionValue) => types.Expression; | ||
export {}; | ||
//# sourceMappingURL=ast-utils.d.ts.map |
@@ -11,6 +11,4 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { | ||
import * as types from '@babel/types'; | ||
import { parse } from '@babel/core'; | ||
import ParsedASTNode from './parsed-ast'; | ||
import { StringUtils } from '@teleporthq/teleport-shared'; | ||
import { ASTUtils } from '..'; | ||
/** | ||
@@ -80,28 +78,2 @@ * Adds a class definition string to an existing string of classes | ||
}; | ||
/** | ||
* Make code expressions happen in AST | ||
* Replace variables that are found in AST with | ||
* the corresponding value from the contexts for now | ||
* and in the future with other sources. | ||
*/ | ||
export var addDynamicExpressionAttributeToJSXTag = function (jsxASTNode, dynamicRef, attrKey, t) { | ||
if (t === void 0) { t = types; } | ||
var dynamicContent = dynamicRef.content; | ||
if (dynamicRef.type !== 'expr') { | ||
throw new Error("This method only works with dynamic nodes that have code expressions"); | ||
} | ||
var code = dynamicContent; | ||
var options = { | ||
sourceType: 'module', | ||
}; | ||
var ast = parse(code, options); | ||
if (!('program' in ast)) { | ||
throw new Error("The AST does not have a program node in the expression inside addDynamicExpressionAttributeToJSXTag"); | ||
} | ||
var theStatementOnlyWihtoutTheProgram = ast.program.body[0]; | ||
if (theStatementOnlyWihtoutTheProgram.type !== 'ExpressionStatement') { | ||
throw new Error("Expr dynamic attribute only support expressions statements at the moment."); | ||
} | ||
jsxASTNode.openingElement.attributes.push(t.jsxAttribute(t.jsxIdentifier(attrKey), t.jsxExpressionContainer(theStatementOnlyWihtoutTheProgram.expression))); | ||
}; | ||
/* | ||
@@ -340,4 +312,4 @@ Use, when we need to add a mix of dynamic and static values to | ||
t.variableDeclarator(t.arrayPattern([ | ||
t.identifier(StringUtils.createStateOrPropStoringValue(stateKey)), | ||
t.identifier(StringUtils.createStateStoringFunction(stateKey)), | ||
t.identifier(stateKey), | ||
t.identifier("set".concat(StringUtils.capitalize(stateKey))), | ||
]), t.callExpression(t.identifier('useState'), [defaultValueArgument])), | ||
@@ -356,260 +328,2 @@ ]); | ||
}; | ||
export var generateRemoteResourceASTs = function (resource) { | ||
var _a, _b; | ||
var fetchUrl = computeFetchUrl(resource); | ||
var authHeaderAST = computeAuthorizationHeaderAST(resource === null || resource === void 0 ? void 0 : resource.headers); | ||
var headersASTs = generateRESTHeadersAST(resource === null || resource === void 0 ? void 0 : resource.headers); | ||
var queryParams = generateURLParamsAST(resource === null || resource === void 0 ? void 0 : resource.params); | ||
var fetchUrlQuasis = fetchUrl.quasis; | ||
var queryParamsQuasis = (queryParams === null || queryParams === void 0 ? void 0 : queryParams.quasis) || [types.templateElement({ raw: '', cooked: '' })]; | ||
if ((queryParams === null || queryParams === void 0 ? void 0 : queryParams.expressions.length) > 0) { | ||
fetchUrlQuasis[fetchUrlQuasis.length - 1].value.raw = | ||
fetchUrlQuasis[fetchUrlQuasis.length - 1].value.raw + '?'; | ||
fetchUrlQuasis[fetchUrlQuasis.length - 1].value.cooked = | ||
fetchUrlQuasis[fetchUrlQuasis.length - 1].value.cooked + '?'; | ||
queryParamsQuasis.pop(); | ||
} | ||
var paramsDeclerations = Object.keys((resource === null || resource === void 0 ? void 0 : resource.params) || {}).reduce(function (acc, item) { | ||
var prop = resource.params[item]; | ||
if (prop.type === 'static') { | ||
acc.push(types.objectProperty(types.stringLiteral(item), ASTUtils.resolveObjectValue(prop))); | ||
} | ||
if (prop.type === 'dynamic') { | ||
acc.push(types.spreadElement(types.logicalExpression('&&', types.memberExpression(types.identifier('params'), types.stringLiteral(prop.content.id), true, false), types.objectExpression([ | ||
types.objectProperty(types.stringLiteral(item), types.memberExpression(types.identifier('params'), types.stringLiteral(prop.content.id), true, false)), | ||
])))); | ||
} | ||
return acc; | ||
}, []); | ||
var paramsAST = types.variableDeclaration('const', [ | ||
types.variableDeclarator(types.identifier('urlParams'), types.objectExpression(paramsDeclerations)), | ||
]); | ||
var url = (queryParams === null || queryParams === void 0 ? void 0 : queryParams.quasis) | ||
? types.templateLiteral(__spreadArray(__spreadArray([], fetchUrlQuasis, true), queryParamsQuasis, true), __spreadArray([], fetchUrl.expressions.concat(queryParams.expressions), true)) | ||
: fetchUrl; | ||
var fetchAST = types.variableDeclaration('const', [ | ||
types.variableDeclarator(types.identifier('data'), types.awaitExpression(types.callExpression(types.identifier('fetch'), [ | ||
url, | ||
types.objectExpression([ | ||
types.objectProperty(types.identifier('method'), types.stringLiteral(resource.method)), | ||
types.objectProperty(types.identifier('headers'), types.objectExpression(__spreadArray(__spreadArray([], headersASTs, true), [authHeaderAST], false))), | ||
]), | ||
]))), | ||
]); | ||
var responseType = (_b = (_a = resource === null || resource === void 0 ? void 0 : resource.response) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : 'json'; | ||
var responseJSONAST; | ||
/** | ||
* Responce types can be of json, text and we might be reading just headers | ||
* So, with the response type of the resource. We are returning either | ||
* - data.json() | ||
* - data.text() | ||
* - data.headers | ||
* back to the caller, from the fetch response. | ||
*/ | ||
switch (responseType) { | ||
case 'json': | ||
responseJSONAST = types.variableDeclaration('const', [ | ||
types.variableDeclarator(types.identifier('response'), types.awaitExpression(types.callExpression(types.memberExpression(types.identifier('data'), types.identifier('json'), false), []))), | ||
]); | ||
break; | ||
case 'text': { | ||
responseJSONAST = types.variableDeclaration('const', [ | ||
types.variableDeclarator(types.identifier('response'), types.awaitExpression(types.callExpression(types.memberExpression(types.identifier('data'), types.identifier('text'), false), []))), | ||
]); | ||
break; | ||
} | ||
case 'headers': { | ||
responseJSONAST = types.variableDeclaration('const', [ | ||
types.variableDeclarator(types.identifier('response'), types.memberExpression(types.identifier('data'), types.identifier('headers'))), | ||
]); | ||
break; | ||
} | ||
case 'none': { | ||
responseJSONAST = types.variableDeclaration('const', [ | ||
types.variableDeclarator(types.identifier('response'), types.identifier('data')), | ||
]); | ||
break; | ||
} | ||
default: { | ||
responseJSONAST = types.variableDeclaration('const', [ | ||
types.variableDeclarator(types.identifier('response'), types.identifier('data')), | ||
]); | ||
} | ||
} | ||
return [paramsAST, fetchAST, responseJSONAST]; | ||
}; | ||
var generateRESTHeadersAST = function (headers) { | ||
return Object.keys(headers) | ||
.filter(function (header) { return header !== 'authToken'; }) | ||
.map(function (header) { | ||
return types.objectProperty(types.stringLiteral(header), types.stringLiteral(String(headers[header].content))); | ||
}); | ||
}; | ||
export var generateMemberExpressionASTFromBase = function (base, path) { | ||
if (path.length === 1) { | ||
return types.memberExpression(base, types.identifier(path[0]), false); | ||
} | ||
var pathClone = __spreadArray([], path, true); | ||
pathClone.pop(); | ||
return types.memberExpression(generateMemberExpressionASTFromBase(base, pathClone), types.identifier(path[path.length - 1]), false); | ||
}; | ||
export var generateMemberExpressionASTFromPath = function (path) { | ||
var pathClone = __spreadArray([], path, true); | ||
if (path.length === 1) { | ||
return types.identifier(path[0].toString()); | ||
} | ||
pathClone.pop(); | ||
var currentPath = path[path.length - 1]; | ||
if (typeof currentPath === 'number') { | ||
return types.memberExpression(generateMemberExpressionASTFromPath(pathClone), types.numericLiteral(currentPath), true); | ||
} | ||
var containsSpecial = currentPath.indexOf('.') !== -1 || currentPath.indexOf('-') !== -1; | ||
return types.memberExpression(generateMemberExpressionASTFromPath(pathClone), containsSpecial ? types.stringLiteral(currentPath) : types.identifier(currentPath), containsSpecial); | ||
}; | ||
export var generateURLParamsAST = function (urlParams) { | ||
if (!urlParams) { | ||
return null; | ||
} | ||
var queryString = {}; | ||
Object.keys(urlParams).forEach(function (key) { | ||
resolveDynamicValuesFromUrlParams(urlParams[key], queryString, key); | ||
}); | ||
return types.templateLiteral([ | ||
types.templateElement({ raw: '', cooked: '' }, false), | ||
types.templateElement({ raw: '', cooked: '' }, true), | ||
], [types.newExpression(types.identifier('URLSearchParams'), [types.identifier('urlParams')])]); | ||
}; | ||
var resolveDynamicValuesFromUrlParams = function (field, query, prefix) { | ||
if (prefix === void 0) { prefix = null; } | ||
if (field.type === 'dynamic' || field.type === 'static') { | ||
query[prefix] = resolveUrlParamsValue(field); | ||
return; | ||
} | ||
}; | ||
var resolveUrlParamsValue = function (urlParam) { | ||
if (urlParam.type === 'static') { | ||
return types.stringLiteral("".concat(urlParam.content)); | ||
} | ||
if (urlParam.content.referenceType !== 'prop' && urlParam.content.referenceType !== 'state') { | ||
throw new Error('Only prop and state references are supported for url params'); | ||
} | ||
var paramPath = __spreadArray(__spreadArray([], (urlParam.content.referenceType === 'prop' ? ['params'] : ['']), true), [ | ||
urlParam.content.id, | ||
], false); | ||
var templateLiteralElements = paramPath | ||
.map(function (_, index) { | ||
var isTail = index === paramPath.length - 1; | ||
return types.templateElement({ | ||
cooked: '', | ||
raw: '', | ||
}, isTail); | ||
}) | ||
.filter(function (el) { return el; }); | ||
return types.templateLiteral(templateLiteralElements, [ | ||
generateMemberExpressionASTFromPath(paramPath), | ||
]); | ||
}; | ||
var computeAuthorizationHeaderAST = function (headers) { | ||
var _a; | ||
var authToken = resolveResourceValue(headers.authToken); | ||
if (!authToken) { | ||
return null; | ||
} | ||
var authTokenType = (_a = headers.authToken) === null || _a === void 0 ? void 0 : _a.type; | ||
return types.objectProperty(types.identifier('Authorization'), types.templateLiteral(__spreadArray([ | ||
types.templateElement({ | ||
cooked: authTokenType === 'static' ? "Bearer ".concat(authToken) : 'Bearer ', | ||
raw: authTokenType === 'static' ? "Bearer ".concat(authToken) : 'Bearer ', | ||
}, false) | ||
], (authTokenType === 'static' | ||
? [] | ||
: [ | ||
types.templateElement({ | ||
cooked: '', | ||
raw: '', | ||
}, true), | ||
]), true), __spreadArray([], (authTokenType === 'static' ? [] : [types.identifier(String(authToken))]), true)), false, false); | ||
}; | ||
var computeFetchUrl = function (resource) { | ||
var _a, _b; | ||
var path = resource.path; | ||
var fetchBaseUrl = resolveResourceValue(path.baseUrl); | ||
var resourceRoute = resolveResourceValue(path.route); | ||
var baseUrlType = (_a = path.baseUrl) === null || _a === void 0 ? void 0 : _a.type; | ||
var routeType = (_b = path.route) === null || _b === void 0 ? void 0 : _b.type; | ||
if (baseUrlType === 'static' && routeType === 'static') { | ||
var stringsToJoin = [fetchBaseUrl, resourceRoute].filter(function (item) { return item; }).join('/'); | ||
return types.templateLiteral([types.templateElement({ cooked: "".concat(stringsToJoin), raw: "".concat(stringsToJoin) }, true)], []); | ||
} | ||
if (!routeType) { | ||
return baseUrlType === 'static' | ||
? types.templateLiteral([types.templateElement({ cooked: "".concat(fetchBaseUrl), raw: "".concat(fetchBaseUrl) }, true)], []) | ||
: types.templateLiteral([ | ||
types.templateElement({ | ||
cooked: '', | ||
raw: '', | ||
}, false), | ||
types.templateElement({ | ||
cooked: '', | ||
raw: '', | ||
}, true), | ||
], [types.identifier(String(fetchBaseUrl))]); | ||
} | ||
return types.templateLiteral(__spreadArray([ | ||
types.templateElement({ | ||
cooked: '', | ||
raw: '', | ||
}, false), | ||
types.templateElement({ | ||
cooked: routeType === 'static' ? "/".concat(resourceRoute) : '/', | ||
raw: routeType === 'static' ? "/".concat(resourceRoute) : '/', | ||
}, false) | ||
], (routeType === 'static' | ||
? [] | ||
: [ | ||
types.templateElement({ | ||
cooked: '', | ||
raw: '', | ||
}, false), | ||
]), true), __spreadArray([ | ||
types.identifier(String(fetchBaseUrl)) | ||
], (routeType === 'static' ? [] : [types.identifier(String(resourceRoute))]), true)); | ||
}; | ||
var resolveResourceValue = function (value) { | ||
if (!value) { | ||
return ''; | ||
} | ||
if (value.type === 'static') { | ||
return value.content; | ||
} | ||
return "process.env.".concat(value.content); | ||
}; | ||
export var resolveObjectValue = function (prop) { | ||
if (prop.type === 'expr') { | ||
return types.identifier(prop.content); | ||
} | ||
var value = typeof prop.content === 'string' | ||
? types.stringLiteral(prop.content) | ||
: typeof prop.content === 'boolean' | ||
? types.booleanLiteral(prop.content) | ||
: typeof prop.content === 'number' | ||
? types.numericLiteral(prop.content) | ||
: typeof prop.content === 'object' | ||
? objectToObjectExpression(prop.content) | ||
: types.identifier(String(prop.content)); | ||
return value; | ||
}; | ||
export var getExpressionFromUIDLExpressionNode = function (node) { | ||
var ast = parse(node.content, { | ||
sourceType: 'module', | ||
}); | ||
if (!('program' in ast)) { | ||
throw new Error("The AST does not have a program node in the expression inside addDynamicExpressionAttributeToJSXTag"); | ||
} | ||
var theStatementOnlyWihtoutTheProgram = ast.program.body[0]; | ||
if (theStatementOnlyWihtoutTheProgram.type !== 'ExpressionStatement') { | ||
throw new Error("Expr dynamic attribute only support expressions statements at the moment."); | ||
} | ||
return theStatementOnlyWihtoutTheProgram.expression; | ||
}; | ||
//# sourceMappingURL=ast-utils.js.map |
{ | ||
"name": "@teleporthq/teleport-plugin-common", | ||
"version": "0.31.0-alpha.0", | ||
"version": "0.31.0", | ||
"description": "Common building and modelating functions for ASTs and HASTs", | ||
@@ -27,9 +27,9 @@ "author": "teleportHQ", | ||
"dependencies": { | ||
"@babel/types": "^7.5.5", | ||
"@teleporthq/teleport-shared": "^0.31.0-alpha.0", | ||
"@teleporthq/teleport-types": "^0.31.0-alpha.0", | ||
"@babel/types": "^7.14.5", | ||
"@teleporthq/teleport-shared": "^0.31.0", | ||
"@teleporthq/teleport-types": "^0.31.0", | ||
"jss": "^10.0.0", | ||
"jss-preset-default": "^10.0.0" | ||
}, | ||
"gitHead": "a5289f88f2d0cf8aae4b93bf05777c5492dd86b2" | ||
"gitHead": "37c3970566832845c57f0ef11088a9214af720b2" | ||
} |
@@ -50,5 +50,13 @@ import jss from 'jss' | ||
export const createFontDecleration = (styleObject: Record<string, string | number>) => { | ||
return jss | ||
.createStyleSheet({ | ||
'@font-face': styleObject, | ||
}) | ||
.toString() | ||
} | ||
export const createCSSClassWithMediaQuery = ( | ||
mediaOffset: string, | ||
styleObject: Record<string, string | number | Record<string, string | number>> | ||
styleObject: Record<string, string | number> | ||
) => { | ||
@@ -89,6 +97,3 @@ return jss | ||
export const generateMediaStyle = ( | ||
styleMap: Record< | ||
string, | ||
Array<{ [x: string]: Record<string, string | number | Record<string, string | number>> }> | ||
> | ||
styleMap: Record<string, Array<{ [x: string]: Record<string, string | number> }>> | ||
) => { | ||
@@ -119,6 +124,3 @@ const styles: string[] = [] | ||
cssMap: string[], | ||
mediaStylesMap: Record< | ||
string, | ||
Array<{ [x: string]: Record<string, string | number | Record<string, string | number>> }> | ||
>, | ||
mediaStylesMap: Record<string, Array<{ [x: string]: Record<string, string | number> }>>, | ||
className: (val: string) => string | ||
@@ -129,4 +131,3 @@ ) => { | ||
const { content, conditions = [], type } = style | ||
const name = className(style.className || styleId) | ||
const subselectors = style.subselectors | ||
const name = className(styleId) | ||
@@ -139,10 +140,6 @@ const { staticStyles, tokenStyles } = UIDLUtils.splitDynamicAndStaticStyles(content) | ||
// & is required by jss, otherwise the final result will be empty | ||
const cls = subselectors | ||
? createCSSClassWithSelector(name, `&${subselectors}`, collectedStyles) | ||
: createCSSClass(name, collectedStyles) | ||
if (type === 'reusable-component-style-map') { | ||
cssMap.unshift(cls) | ||
cssMap.unshift(createCSSClass(name, collectedStyles)) | ||
} else { | ||
cssMap.push(cls) | ||
cssMap.push(createCSSClass(name, collectedStyles)) | ||
} | ||
@@ -165,15 +162,7 @@ | ||
cssMap.unshift( | ||
createCSSClassWithSelector( | ||
name, | ||
`&${subselectors || ''}:${styleRef.meta.state}`, | ||
collecedMediaStyles | ||
) | ||
createCSSClassWithSelector(name, `&:${styleRef.meta.state}`, collecedMediaStyles) | ||
) | ||
} else { | ||
cssMap.push( | ||
createCSSClassWithSelector( | ||
name, | ||
`&${subselectors || ''}:${styleRef.meta.state}`, | ||
collecedMediaStyles | ||
) | ||
createCSSClassWithSelector(name, `&:${styleRef.meta.state}`, collecedMediaStyles) | ||
) | ||
@@ -189,10 +178,6 @@ } | ||
const mediaStyleMap = subselectors | ||
? { [`&${subselectors}`]: collecedMediaStyles } | ||
: collecedMediaStyles | ||
if (type === 'reusable-component-style-map') { | ||
mediaStylesMap[String(maxWidth)].unshift({ [name]: mediaStyleMap }) | ||
mediaStylesMap[String(maxWidth)].unshift({ [name]: collecedMediaStyles }) | ||
} else { | ||
mediaStylesMap[String(maxWidth)].push({ [name]: mediaStyleMap }) | ||
mediaStylesMap[String(maxWidth)].push({ [name]: collecedMediaStyles }) | ||
} | ||
@@ -199,0 +184,0 @@ } |
@@ -91,4 +91,12 @@ import * as hastUtils from '../../utils/hast-utils' | ||
switch (node.type) { | ||
case 'inject': | ||
if (node?.dependency) { | ||
/* tslint:disable:no-string-literal */ | ||
params.dependencies['Script'] = node.dependency | ||
} | ||
return node.content.toString() | ||
case 'raw': | ||
return generateRawHTMLNode(node, params, templateSyntax) | ||
case 'static': | ||
@@ -95,0 +103,0 @@ return StringUtils.encode(node.content.toString()) |
@@ -24,2 +24,3 @@ import * as hastUtils from '../../utils/hast-utils' | ||
const dynamicAttrKey = templateSyntax.valueBinding(attrKey, node) | ||
switch (attrValue.type) { | ||
@@ -26,0 +27,0 @@ case 'dynamic': |
@@ -10,6 +10,2 @@ import * as types from '@babel/types' | ||
UIDLNode, | ||
UIDLCMSListNode, | ||
UIDLCMSItemNode, | ||
UIDLExpressionValue, | ||
UIDLCMSListRepeaterNode, | ||
} from '@teleporthq/teleport-types' | ||
@@ -33,8 +29,5 @@ import { UIDLUtils, StringUtils } from '@teleporthq/teleport-shared' | ||
generateDynamicWindowImport, | ||
addDynamicExpressionAttributeToJSXTag, | ||
resolveObjectValue, | ||
} from '../../utils/ast-utils' | ||
import { createJSXTag, createSelfClosingJSXTag } from '../../builders/ast-builders' | ||
import { DEFAULT_JSX_OPTIONS } from './constants' | ||
import { ASTBuilders, ASTUtils } from '../..' | ||
@@ -46,4 +39,4 @@ const generateElementNode: NodeToJSX<UIDLElementNode, types.JSXElement> = ( | ||
) => { | ||
const { dependencies, nodesLookup, projectResources = {} } = params | ||
const options = { ...DEFAULT_JSX_OPTIONS, ...jsxOptions, projectResources } | ||
const options = { ...DEFAULT_JSX_OPTIONS, ...jsxOptions } | ||
const { dependencies, nodesLookup } = params | ||
const { elementType, selfClosing, children, key, attrs, dependency, events } = node.content | ||
@@ -96,18 +89,7 @@ | ||
const { | ||
content: { referenceType }, | ||
content: { id, referenceType }, | ||
} = attributeValue | ||
switch (referenceType) { | ||
default: | ||
const prefix = | ||
options.dynamicReferencePrefixMap[referenceType as 'prop' | 'state' | 'local'] | ||
addDynamicAttributeToJSXTag( | ||
elementTag, | ||
attrKey, | ||
(attributeValue as UIDLDynamicReference).content.id, | ||
prefix | ||
) | ||
break | ||
} | ||
const prefix = | ||
options.dynamicReferencePrefixMap[referenceType as 'prop' | 'state' | 'local'] | ||
addDynamicAttributeToJSXTag(elementTag, attrKey, id, prefix) | ||
break | ||
@@ -122,7 +104,5 @@ case 'import': | ||
case 'static': | ||
addAttributeToJSXTag(elementTag, attrKey, attributeValue.content) | ||
const { content } = attributeValue | ||
addAttributeToJSXTag(elementTag, attrKey, content) | ||
break | ||
case 'expr': | ||
addDynamicExpressionAttributeToJSXTag(elementTag, attributeValue, attrKey) | ||
break | ||
default: | ||
@@ -146,12 +126,11 @@ throw new Error( | ||
children.forEach((child) => { | ||
const childTags = generateNode(child, params, options) | ||
childTags.forEach((childTag) => { | ||
if (typeof childTag === 'string') { | ||
addChildJSXText(elementTag, childTag) | ||
} else if (childTag.type === 'JSXExpressionContainer' || childTag.type === 'JSXElement') { | ||
addChildJSXTag(elementTag, childTag) | ||
} else { | ||
addChildJSXTag(elementTag, types.jsxExpressionContainer(childTag)) | ||
} | ||
}) | ||
const childTag = generateNode(child, params, options) | ||
if (typeof childTag === 'string') { | ||
addChildJSXText(elementTag, childTag) | ||
} else if (childTag.type === 'JSXExpressionContainer' || childTag.type === 'JSXElement') { | ||
addChildJSXTag(elementTag, childTag) | ||
} else { | ||
addChildJSXTag(elementTag, types.jsxExpressionContainer(childTag)) | ||
} | ||
}) | ||
@@ -166,24 +145,24 @@ } | ||
const generateNode: NodeToJSX<UIDLNode, JSXASTReturnType[]> = (node, params, options) => { | ||
const generateNode: NodeToJSX<UIDLNode, JSXASTReturnType> = (node, params, options) => { | ||
switch (node.type) { | ||
case 'expr': | ||
return [generateExpressionNode(node, params, options)] | ||
case 'inject': | ||
if (node?.dependency) { | ||
/* tslint:disable:no-string-literal */ | ||
params.dependencies['Script'] = node.dependency | ||
} | ||
return node.content.toString() | ||
case 'raw': | ||
return [ | ||
options.domHTMLInjection | ||
? options.domHTMLInjection(node.content.toString()) | ||
: node.content.toString(), | ||
] | ||
return options.domHTMLInjection | ||
? options.domHTMLInjection(node.content.toString()) | ||
: node.content.toString() | ||
case 'static': | ||
return [StringUtils.encode(node.content.toString())] | ||
return StringUtils.encode(node.content.toString()) | ||
case 'dynamic': | ||
return [createDynamicValueExpression(node, options, undefined)] | ||
return createDynamicValueExpression(node, options) | ||
case 'cms-item': | ||
case 'cms-list': | ||
return generateCMSNode(node, params, options) | ||
case 'element': | ||
return [generateElementNode(node, params, options)] | ||
return generateElementNode(node, params, options) | ||
@@ -196,8 +175,5 @@ case 'repeat': | ||
case 'cms-list-repeater': | ||
return generateCMSListRepeaterNode(node, params, options) | ||
case 'slot': | ||
if (options.slotHandling === 'native') { | ||
return [generateNativeSlotNode(node, params, options)] | ||
return generateNativeSlotNode(node, params, options) | ||
} else { | ||
@@ -218,10 +194,3 @@ return generatePropsSlotNode(node, params, options) | ||
const generateExpressionNode: NodeToJSX<UIDLExpressionValue, types.JSXExpressionContainer> = ( | ||
node | ||
) => { | ||
const expression = ASTUtils.getExpressionFromUIDLExpressionNode(node) | ||
return types.jsxExpressionContainer(expression) | ||
} | ||
const generateCMSNode: NodeToJSX<UIDLCMSListNode | UIDLCMSItemNode, types.JSXElement[]> = ( | ||
const generateRepeatNode: NodeToJSX<UIDLRepeatNode, types.JSXExpressionContainer> = ( | ||
node, | ||
@@ -231,158 +200,10 @@ params, | ||
) => { | ||
const { | ||
initialData, | ||
key, | ||
renderPropIdentifier, | ||
resource: { params: resourceParams } = {}, | ||
router, | ||
elementType, | ||
dependency, | ||
} = node.content | ||
const { loading, error, success } = node.content.nodes | ||
const jsxTag = StringUtils.dashCaseToUpperCamelCase(elementType) | ||
const { node: repeatContent, dataSource, meta } = node.content | ||
if (router && options?.dependencyHandling === 'import') { | ||
params.dependencies.useRouter = router | ||
} | ||
const contentAST = generateElementNode(repeatContent, params, options) | ||
if (!success) { | ||
return [] | ||
} | ||
if (dependency && options.dependencyHandling === 'import') { | ||
params.dependencies[elementType] = dependency | ||
} | ||
const cmsNode = ASTBuilders.createJSXTag(jsxTag, [], true) | ||
if (node.type === 'cms-item') { | ||
cmsNode.openingElement.attributes.push( | ||
types.jsxAttribute( | ||
types.jsxIdentifier('renderSuccess'), | ||
types.jsxExpressionContainer( | ||
types.arrowFunctionExpression( | ||
[types.identifier(renderPropIdentifier)], | ||
generateNode(success, params, options)[0] as types.JSXElement | ||
) | ||
) | ||
) | ||
) | ||
} | ||
if (node.type === 'cms-list') { | ||
cmsNode.openingElement.attributes.push( | ||
types.jsxAttribute( | ||
types.jsxIdentifier('renderSuccess'), | ||
types.jsxExpressionContainer( | ||
types.arrowFunctionExpression( | ||
[types.identifier('params')], | ||
generateNode(success, params, options)[0] as types.JSXElement | ||
) | ||
) | ||
) | ||
) | ||
} | ||
if (dependency && options.dependencyHandling === 'import') { | ||
params.dependencies.Repeater = dependency | ||
} | ||
if (loading) { | ||
cmsNode.openingElement.attributes.push( | ||
types.jsxAttribute( | ||
types.jsxIdentifier('renderLoading'), | ||
types.jsxExpressionContainer( | ||
types.arrowFunctionExpression( | ||
[], | ||
generateNode(loading, params, options)[0] as types.JSXElement | ||
) | ||
) | ||
) | ||
) | ||
} | ||
if (error) { | ||
cmsNode.openingElement.attributes.push( | ||
types.jsxAttribute( | ||
types.jsxIdentifier('renderError'), | ||
types.jsxExpressionContainer( | ||
types.arrowFunctionExpression( | ||
[], | ||
generateNode(error, params, options)[0] as types.JSXElement | ||
) | ||
) | ||
) | ||
) | ||
} | ||
if (initialData && initialData.content.referenceType === 'prop') { | ||
cmsNode.openingElement.attributes.push( | ||
types.jsxAttribute( | ||
types.jsxIdentifier('initialData'), | ||
types.jsxExpressionContainer( | ||
types.memberExpression( | ||
types.identifier(options.dynamicReferencePrefixMap[initialData.content.referenceType]), | ||
types.identifier(initialData.content.id) | ||
) | ||
) | ||
) | ||
) | ||
cmsNode.openingElement.attributes.push( | ||
types.jsxAttribute( | ||
types.jsxIdentifier('persistDataDuringLoading'), | ||
types.jsxExpressionContainer(types.booleanLiteral(true)) | ||
) | ||
) | ||
cmsNode.openingElement.attributes.push( | ||
types.jsxAttribute( | ||
types.jsxIdentifier('key'), | ||
types.jsxExpressionContainer(types.identifier('props.page')) | ||
) | ||
) | ||
} | ||
if (Object.keys(resourceParams || {}).length > 0) { | ||
const nodeParams: types.ObjectProperty[] = Object.keys(resourceParams).reduce( | ||
(acc: types.ObjectProperty[], attrKey) => { | ||
const property = resourceParams[attrKey] | ||
if (property.type === 'static') { | ||
acc.push(types.objectProperty(types.stringLiteral(attrKey), resolveObjectValue(property))) | ||
} | ||
if (property.type === 'expr') { | ||
const expression = ASTUtils.getExpressionFromUIDLExpressionNode(property) | ||
acc.push(types.objectProperty(types.stringLiteral(attrKey), expression)) | ||
} | ||
return acc | ||
}, | ||
[] | ||
) | ||
cmsNode.openingElement.attributes.push( | ||
types.jsxAttribute( | ||
types.jsxIdentifier('params'), | ||
types.jsxExpressionContainer(types.objectExpression(nodeParams)) | ||
) | ||
) | ||
} | ||
params.nodesLookup[key] = cmsNode | ||
return [cmsNode] | ||
} | ||
const generateRepeatNode: NodeToJSX<UIDLRepeatNode, types.JSXExpressionContainer[]> = ( | ||
node, | ||
params, | ||
options | ||
) => { | ||
const { node: repeatContent, dataSource, meta } = node.content | ||
const contentASTs = generateNode(repeatContent, params, options) as types.JSXElement[] | ||
const { iteratorName, iteratorKey } = UIDLUtils.getRepeatIteratorNameAndKey(meta) | ||
const localIteratorPrefix = options.dynamicReferencePrefixMap.local | ||
contentASTs.forEach((contentAST) => { | ||
addDynamicAttributeToJSXTag(contentAST, 'key', iteratorKey, localIteratorPrefix) | ||
}) | ||
addDynamicAttributeToJSXTag(contentAST, 'key', iteratorKey, localIteratorPrefix) | ||
@@ -396,12 +217,10 @@ const source = getRepeatSourceIdentifier(dataSource, options) | ||
return contentASTs.map((contentAST) => | ||
types.jsxExpressionContainer( | ||
types.callExpression(types.memberExpression(source, types.identifier('map')), [ | ||
types.arrowFunctionExpression(arrowFunctionArguments, contentAST), | ||
]) | ||
) | ||
return types.jsxExpressionContainer( | ||
types.callExpression(types.memberExpression(source, types.identifier('map')), [ | ||
types.arrowFunctionExpression(arrowFunctionArguments, contentAST), | ||
]) | ||
) | ||
} | ||
const generateConditionalNode: NodeToJSX<UIDLConditionalNode, types.LogicalExpression[]> = ( | ||
const generateConditionalNode: NodeToJSX<UIDLConditionalNode, types.LogicalExpression> = ( | ||
node, | ||
@@ -414,3 +233,3 @@ params, | ||
const subTrees = generateNode(node.content.node, params, options) | ||
const subTree = generateNode(node.content.node, params, options) | ||
@@ -422,50 +241,6 @@ const condition: UIDLConditionalExpression = | ||
return subTrees.map((subTree) => | ||
createConditionalJSXExpression(subTree, condition, conditionIdentifier) | ||
) | ||
return createConditionalJSXExpression(subTree, condition, conditionIdentifier) | ||
} | ||
const generateCMSListRepeaterNode: NodeToJSX<UIDLCMSListRepeaterNode, types.JSXElement[]> = ( | ||
node, | ||
params, | ||
options | ||
) => { | ||
const repeaterNode = ASTBuilders.createJSXTag('Repeater', [], true) | ||
repeaterNode.openingElement.attributes.push( | ||
types.jsxAttribute( | ||
types.jsxIdentifier('items'), | ||
types.jsxExpressionContainer(types.identifier('params')) | ||
) | ||
) | ||
repeaterNode.openingElement.attributes.push( | ||
types.jsxAttribute( | ||
types.jSXIdentifier('renderItem'), | ||
types.jsxExpressionContainer( | ||
types.arrowFunctionExpression( | ||
[types.identifier(node.content.renderPropIdentifier)], | ||
generateNode(node.content.nodes.list, params, options)[0] as types.JSXElement | ||
) | ||
) | ||
) | ||
) | ||
if ('empty' in node.content.nodes) { | ||
repeaterNode.openingElement.attributes.push( | ||
types.jsxAttribute( | ||
types.jsxIdentifier('renderEmpty'), | ||
types.jsxExpressionContainer( | ||
types.arrowFunctionExpression( | ||
[], | ||
generateNode(node.content.nodes.empty, params, options)[0] as types.JSXElement | ||
) | ||
) | ||
) | ||
) | ||
} | ||
return [repeaterNode] | ||
} | ||
const generatePropsSlotNode: NodeToJSX<UIDLSlotNode, types.JSXExpressionContainer[]> = ( | ||
const generatePropsSlotNode: NodeToJSX<UIDLSlotNode, types.JSXExpressionContainer> = ( | ||
node: UIDLSlotNode, | ||
@@ -488,19 +263,16 @@ params, | ||
if (node.content.fallback) { | ||
const fallbackContents = generateNode(node.content.fallback, params, options) | ||
const fallbackContent = generateNode(node.content.fallback, params, options) | ||
// only static dynamic or element are allowed here | ||
const fallbackNode = | ||
typeof fallbackContent === 'string' | ||
? types.stringLiteral(fallbackContent) | ||
: (fallbackContent as types.JSXElement | types.MemberExpression) | ||
return fallbackContents.map((fallbackContent) => { | ||
const fallbackNode = | ||
typeof fallbackContent === 'string' | ||
? types.stringLiteral(fallbackContent) | ||
: (fallbackContent as types.JSXElement | types.MemberExpression) | ||
// props.children with fallback | ||
return types.jsxExpressionContainer( | ||
types.logicalExpression('||', childrenExpression, fallbackNode) | ||
) | ||
}) | ||
// props.children with fallback | ||
return types.jsxExpressionContainer( | ||
types.logicalExpression('||', childrenExpression, fallbackNode) | ||
) | ||
} | ||
return [types.jsxExpressionContainer(childrenExpression)] | ||
return types.jsxExpressionContainer(childrenExpression) | ||
} | ||
@@ -520,13 +292,10 @@ | ||
if (node.content.fallback) { | ||
const fallbackContents = generateNode(node.content.fallback, params, options) | ||
fallbackContents.forEach((fallbackContent) => { | ||
if (typeof fallbackContent === 'string') { | ||
addChildJSXText(slotNode, fallbackContent) | ||
} else if (fallbackContent.type === 'MemberExpression') { | ||
addChildJSXTag(slotNode, types.jsxExpressionContainer(fallbackContent)) | ||
} else { | ||
addChildJSXTag(slotNode, fallbackContent as types.JSXElement) | ||
} | ||
}) | ||
const fallbackContent = generateNode(node.content.fallback, params, options) | ||
if (typeof fallbackContent === 'string') { | ||
addChildJSXText(slotNode, fallbackContent) | ||
} else if (fallbackContent.type === 'MemberExpression') { | ||
addChildJSXTag(slotNode, types.jsxExpressionContainer(fallbackContent)) | ||
} else { | ||
addChildJSXTag(slotNode, fallbackContent as types.JSXElement) | ||
} | ||
} | ||
@@ -533,0 +302,0 @@ |
import * as types from '@babel/types' | ||
import { | ||
UIDLPropDefinition, | ||
UIDLDependency, | ||
UIDLStateDefinition, | ||
ProjectResource, | ||
} from '@teleporthq/teleport-types' | ||
import { UIDLPropDefinition, UIDLDependency, UIDLStateDefinition } from '@teleporthq/teleport-types' | ||
@@ -16,3 +11,2 @@ export interface JSXGenerationParams { | ||
windowImports: Record<string, types.ExpressionStatement> | ||
projectResources?: Record<string, ProjectResource> | ||
} | ||
@@ -19,0 +13,0 @@ |
@@ -127,5 +127,3 @@ import * as types from '@babel/types' | ||
return t.expressionStatement( | ||
t.callExpression(t.identifier(StringUtils.createStateStoringFunction(stateKey)), [ | ||
newStateValue, | ||
]) | ||
t.callExpression(t.identifier(`set${StringUtils.capitalize(stateKey)}`), [newStateValue]) | ||
) | ||
@@ -151,18 +149,11 @@ case 'function': | ||
) => { | ||
const identifierContent = identifier.content | ||
const { referenceType, id } = identifierContent | ||
if (referenceType === 'attr' || referenceType === 'children' || referenceType === 'token') { | ||
throw new Error(`Dynamic reference type "${referenceType}" is not supported yet`) | ||
} | ||
const prefix = | ||
options.dynamicReferencePrefixMap[referenceType as 'prop' | 'state' | 'local'] || '' | ||
const refType = identifier.content.referenceType as 'prop' | 'state' | 'local' | ||
const prefix = options.dynamicReferencePrefixMap[refType] || '' | ||
return prefix === '' | ||
? t.identifier(id) | ||
: t.memberExpression(t.identifier(prefix), t.identifier(id)) | ||
? t.identifier(identifier.content.id) | ||
: t.memberExpression(t.identifier(prefix), t.identifier(identifier.content.id)) | ||
} | ||
// Prepares an identifier (from props or state or an expr) to be used as a conditional rendering identifier | ||
// Assumes the type from the corresponding props/state definitions if not expr. Expressions are expected to have a boolean return here | ||
// Prepares an identifier (from props or state) to be used as a conditional rendering identifier | ||
// Assumes the type from the corresponding props/state definitions | ||
export const createConditionIdentifier = ( | ||
@@ -191,7 +182,2 @@ dynamicReference: UIDLDynamicReference, | ||
} | ||
case 'expr': | ||
return { | ||
key: id, | ||
type: 'boolean', | ||
} | ||
default: | ||
@@ -198,0 +184,0 @@ throw new Error( |
declare module 'jss-preset-default' | ||
declare module 'qs' |
import * as types from '@babel/types' | ||
import { parse } from '@babel/core' | ||
import ParsedASTNode from './parsed-ast' | ||
import { StringUtils } from '@teleporthq/teleport-shared' | ||
import { | ||
UIDLStateDefinition, | ||
UIDLPropDefinition, | ||
UIDLRawValue, | ||
UIDLStaticValue, | ||
UIDLResourceItem, | ||
UIDLENVValue, | ||
UIDLPropValue, | ||
UIDLExpressionValue, | ||
UIDLStateValue, | ||
} from '@teleporthq/teleport-types' | ||
import { ASTUtils } from '..' | ||
import { UIDLStateDefinition, UIDLPropDefinition, UIDLRawValue } from '@teleporthq/teleport-types' | ||
/** | ||
@@ -114,46 +101,2 @@ * Adds a class definition string to an existing string of classes | ||
/** | ||
* Make code expressions happen in AST | ||
* Replace variables that are found in AST with | ||
* the corresponding value from the contexts for now | ||
* and in the future with other sources. | ||
*/ | ||
export const addDynamicExpressionAttributeToJSXTag = ( | ||
jsxASTNode: types.JSXElement, | ||
dynamicRef: UIDLExpressionValue, | ||
attrKey: string, | ||
t = types | ||
) => { | ||
const dynamicContent = dynamicRef.content | ||
if (dynamicRef.type !== 'expr') { | ||
throw new Error(`This method only works with dynamic nodes that have code expressions`) | ||
} | ||
const code = dynamicContent | ||
const options = { | ||
sourceType: 'module' as const, | ||
} | ||
const ast = parse(code, options) | ||
if (!('program' in ast)) { | ||
throw new Error( | ||
`The AST does not have a program node in the expression inside addDynamicExpressionAttributeToJSXTag` | ||
) | ||
} | ||
const theStatementOnlyWihtoutTheProgram = ast.program.body[0] | ||
if (theStatementOnlyWihtoutTheProgram.type !== 'ExpressionStatement') { | ||
throw new Error(`Expr dynamic attribute only support expressions statements at the moment.`) | ||
} | ||
jsxASTNode.openingElement.attributes.push( | ||
t.jsxAttribute( | ||
t.jsxIdentifier(attrKey), | ||
t.jsxExpressionContainer(theStatementOnlyWihtoutTheProgram.expression) | ||
) | ||
) | ||
} | ||
/* | ||
@@ -517,4 +460,4 @@ Use, when we need to add a mix of dynamic and static values to | ||
t.arrayPattern([ | ||
t.identifier(StringUtils.createStateOrPropStoringValue(stateKey)), | ||
t.identifier(StringUtils.createStateStoringFunction(stateKey)), | ||
t.identifier(stateKey), | ||
t.identifier(`set${StringUtils.capitalize(stateKey)}`), | ||
]), | ||
@@ -543,449 +486,1 @@ t.callExpression(t.identifier('useState'), [defaultValueArgument]) | ||
types.objectExpression(properties) | ||
export const generateRemoteResourceASTs = (resource: UIDLResourceItem) => { | ||
const fetchUrl = computeFetchUrl(resource) | ||
const authHeaderAST = computeAuthorizationHeaderAST(resource?.headers) | ||
const headersASTs = generateRESTHeadersAST(resource?.headers) | ||
const queryParams = generateURLParamsAST(resource?.params) | ||
const fetchUrlQuasis = fetchUrl.quasis | ||
const queryParamsQuasis = queryParams?.quasis || [types.templateElement({ raw: '', cooked: '' })] | ||
if (queryParams?.expressions.length > 0) { | ||
fetchUrlQuasis[fetchUrlQuasis.length - 1].value.raw = | ||
fetchUrlQuasis[fetchUrlQuasis.length - 1].value.raw + '?' | ||
fetchUrlQuasis[fetchUrlQuasis.length - 1].value.cooked = | ||
fetchUrlQuasis[fetchUrlQuasis.length - 1].value.cooked + '?' | ||
queryParamsQuasis.pop() | ||
} | ||
const paramsDeclerations: Array<types.ObjectProperty | types.SpreadElement> = Object.keys( | ||
resource?.params || {} | ||
).reduce((acc: Array<types.ObjectProperty | types.SpreadElement>, item) => { | ||
const prop = resource.params[item] | ||
if (prop.type === 'static') { | ||
acc.push(types.objectProperty(types.stringLiteral(item), ASTUtils.resolveObjectValue(prop))) | ||
} | ||
if (prop.type === 'dynamic') { | ||
acc.push( | ||
types.spreadElement( | ||
types.logicalExpression( | ||
'&&', | ||
types.memberExpression( | ||
types.identifier('params'), | ||
types.stringLiteral(prop.content.id), | ||
true, | ||
false | ||
), | ||
types.objectExpression([ | ||
types.objectProperty( | ||
types.stringLiteral(item), | ||
types.memberExpression( | ||
types.identifier('params'), | ||
types.stringLiteral(prop.content.id), | ||
true, | ||
false | ||
) | ||
), | ||
]) | ||
) | ||
) | ||
) | ||
} | ||
return acc | ||
}, []) | ||
const paramsAST = types.variableDeclaration('const', [ | ||
types.variableDeclarator( | ||
types.identifier('urlParams'), | ||
types.objectExpression(paramsDeclerations) | ||
), | ||
]) | ||
const url = queryParams?.quasis | ||
? types.templateLiteral( | ||
[...fetchUrlQuasis, ...queryParamsQuasis], | ||
[...fetchUrl.expressions.concat(queryParams.expressions)] | ||
) | ||
: fetchUrl | ||
const fetchAST = types.variableDeclaration('const', [ | ||
types.variableDeclarator( | ||
types.identifier('data'), | ||
types.awaitExpression( | ||
types.callExpression(types.identifier('fetch'), [ | ||
url, | ||
types.objectExpression([ | ||
types.objectProperty(types.identifier('method'), types.stringLiteral(resource.method)), | ||
types.objectProperty( | ||
types.identifier('headers'), | ||
types.objectExpression([...headersASTs, authHeaderAST]) | ||
), | ||
]), | ||
]) | ||
) | ||
), | ||
]) | ||
const responseType = resource?.response?.type ?? 'json' | ||
let responseJSONAST | ||
/** | ||
* Responce types can be of json, text and we might be reading just headers | ||
* So, with the response type of the resource. We are returning either | ||
* - data.json() | ||
* - data.text() | ||
* - data.headers | ||
* back to the caller, from the fetch response. | ||
*/ | ||
switch (responseType) { | ||
case 'json': | ||
responseJSONAST = types.variableDeclaration('const', [ | ||
types.variableDeclarator( | ||
types.identifier('response'), | ||
types.awaitExpression( | ||
types.callExpression( | ||
types.memberExpression(types.identifier('data'), types.identifier('json'), false), | ||
[] | ||
) | ||
) | ||
), | ||
]) | ||
break | ||
case 'text': { | ||
responseJSONAST = types.variableDeclaration('const', [ | ||
types.variableDeclarator( | ||
types.identifier('response'), | ||
types.awaitExpression( | ||
types.callExpression( | ||
types.memberExpression(types.identifier('data'), types.identifier('text'), false), | ||
[] | ||
) | ||
) | ||
), | ||
]) | ||
break | ||
} | ||
case 'headers': { | ||
responseJSONAST = types.variableDeclaration('const', [ | ||
types.variableDeclarator( | ||
types.identifier('response'), | ||
types.memberExpression(types.identifier('data'), types.identifier('headers')) | ||
), | ||
]) | ||
break | ||
} | ||
case 'none': { | ||
responseJSONAST = types.variableDeclaration('const', [ | ||
types.variableDeclarator(types.identifier('response'), types.identifier('data')), | ||
]) | ||
break | ||
} | ||
default: { | ||
responseJSONAST = types.variableDeclaration('const', [ | ||
types.variableDeclarator(types.identifier('response'), types.identifier('data')), | ||
]) | ||
} | ||
} | ||
return [paramsAST, fetchAST, responseJSONAST] | ||
} | ||
const generateRESTHeadersAST = (headers: UIDLResourceItem['headers']): types.ObjectProperty[] => { | ||
return Object.keys(headers) | ||
.filter((header) => header !== 'authToken') | ||
.map((header) => { | ||
return types.objectProperty( | ||
types.stringLiteral(header), | ||
types.stringLiteral(String(headers[header].content)) | ||
) | ||
}) | ||
} | ||
export const generateMemberExpressionASTFromBase = ( | ||
base: types.MemberExpression | types.Identifier, | ||
path: string[] | ||
): types.MemberExpression => { | ||
if (path.length === 1) { | ||
return types.memberExpression(base, types.identifier(path[0]), false) | ||
} | ||
const pathClone = [...path] | ||
pathClone.pop() | ||
return types.memberExpression( | ||
generateMemberExpressionASTFromBase(base, pathClone), | ||
types.identifier(path[path.length - 1]), | ||
false | ||
) | ||
} | ||
export const generateMemberExpressionASTFromPath = ( | ||
path: Array<string | number> | ||
): types.MemberExpression | types.Identifier => { | ||
const pathClone = [...path] | ||
if (path.length === 1) { | ||
return types.identifier(path[0].toString()) | ||
} | ||
pathClone.pop() | ||
const currentPath = path[path.length - 1] | ||
if (typeof currentPath === 'number') { | ||
return types.memberExpression( | ||
generateMemberExpressionASTFromPath(pathClone), | ||
types.numericLiteral(currentPath), | ||
true | ||
) | ||
} | ||
const containsSpecial = currentPath.indexOf('.') !== -1 || currentPath.indexOf('-') !== -1 | ||
return types.memberExpression( | ||
generateMemberExpressionASTFromPath(pathClone), | ||
containsSpecial ? types.stringLiteral(currentPath) : types.identifier(currentPath), | ||
containsSpecial | ||
) | ||
} | ||
export const generateURLParamsAST = ( | ||
urlParams: Record<string, UIDLStaticValue | UIDLStateValue | UIDLPropValue> | ||
): types.TemplateLiteral | null => { | ||
if (!urlParams) { | ||
return null | ||
} | ||
const queryString: Record<string, types.Expression> = {} | ||
Object.keys(urlParams).forEach((key) => { | ||
resolveDynamicValuesFromUrlParams(urlParams[key], queryString, key) | ||
}) | ||
return types.templateLiteral( | ||
[ | ||
types.templateElement({ raw: '', cooked: '' }, false), | ||
types.templateElement({ raw: '', cooked: '' }, true), | ||
], | ||
[types.newExpression(types.identifier('URLSearchParams'), [types.identifier('urlParams')])] | ||
) | ||
} | ||
const resolveDynamicValuesFromUrlParams = ( | ||
field: UIDLStaticValue | UIDLPropValue | UIDLStateValue, | ||
query: Record<string, types.Expression>, | ||
prefix: string = null | ||
) => { | ||
if (field.type === 'dynamic' || field.type === 'static') { | ||
query[prefix] = resolveUrlParamsValue(field) | ||
return | ||
} | ||
} | ||
const resolveUrlParamsValue = (urlParam: UIDLStaticValue | UIDLPropValue | UIDLStateValue) => { | ||
if (urlParam.type === 'static') { | ||
return types.stringLiteral(`${urlParam.content}`) | ||
} | ||
if (urlParam.content.referenceType !== 'prop' && urlParam.content.referenceType !== 'state') { | ||
throw new Error('Only prop and state references are supported for url params') | ||
} | ||
const paramPath = [ | ||
...(urlParam.content.referenceType === 'prop' ? ['params'] : ['']), | ||
urlParam.content.id, | ||
] | ||
const templateLiteralElements = paramPath | ||
.map((_, index) => { | ||
const isTail = index === paramPath.length - 1 | ||
return types.templateElement( | ||
{ | ||
cooked: '', | ||
raw: '', | ||
}, | ||
isTail | ||
) | ||
}) | ||
.filter((el) => el) | ||
return types.templateLiteral(templateLiteralElements, [ | ||
generateMemberExpressionASTFromPath(paramPath), | ||
]) | ||
} | ||
const computeAuthorizationHeaderAST = (headers: UIDLResourceItem['headers']) => { | ||
const authToken = resolveResourceValue(headers.authToken) | ||
if (!authToken) { | ||
return null | ||
} | ||
const authTokenType = headers.authToken?.type | ||
return types.objectProperty( | ||
types.identifier('Authorization'), | ||
types.templateLiteral( | ||
[ | ||
types.templateElement( | ||
{ | ||
cooked: authTokenType === 'static' ? `Bearer ${authToken}` : 'Bearer ', | ||
raw: authTokenType === 'static' ? `Bearer ${authToken}` : 'Bearer ', | ||
}, | ||
false | ||
), | ||
...(authTokenType === 'static' | ||
? [] | ||
: [ | ||
types.templateElement( | ||
{ | ||
cooked: '', | ||
raw: '', | ||
}, | ||
true | ||
), | ||
]), | ||
], | ||
[...(authTokenType === 'static' ? [] : [types.identifier(String(authToken))])] | ||
), | ||
false, | ||
false | ||
) | ||
} | ||
const computeFetchUrl = (resource: UIDLResourceItem) => { | ||
const { path } = resource | ||
const fetchBaseUrl = resolveResourceValue(path.baseUrl) | ||
const resourceRoute = resolveResourceValue(path.route) | ||
const baseUrlType = path.baseUrl?.type | ||
const routeType = path.route?.type | ||
if (baseUrlType === 'static' && routeType === 'static') { | ||
const stringsToJoin = [fetchBaseUrl, resourceRoute].filter((item) => item).join('/') | ||
return types.templateLiteral( | ||
[types.templateElement({ cooked: `${stringsToJoin}`, raw: `${stringsToJoin}` }, true)], | ||
[] | ||
) | ||
} | ||
if (!routeType) { | ||
return baseUrlType === 'static' | ||
? types.templateLiteral( | ||
[types.templateElement({ cooked: `${fetchBaseUrl}`, raw: `${fetchBaseUrl}` }, true)], | ||
[] | ||
) | ||
: types.templateLiteral( | ||
[ | ||
types.templateElement( | ||
{ | ||
cooked: '', | ||
raw: '', | ||
}, | ||
false | ||
), | ||
types.templateElement( | ||
{ | ||
cooked: '', | ||
raw: '', | ||
}, | ||
true | ||
), | ||
], | ||
[types.identifier(String(fetchBaseUrl))] | ||
) | ||
} | ||
return types.templateLiteral( | ||
[ | ||
types.templateElement( | ||
{ | ||
cooked: '', | ||
raw: '', | ||
}, | ||
false | ||
), | ||
types.templateElement( | ||
{ | ||
cooked: routeType === 'static' ? `/${resourceRoute}` : '/', | ||
raw: routeType === 'static' ? `/${resourceRoute}` : '/', | ||
}, | ||
false | ||
), | ||
...(routeType === 'static' | ||
? [] | ||
: [ | ||
types.templateElement( | ||
{ | ||
cooked: '', | ||
raw: '', | ||
}, | ||
false | ||
), | ||
]), | ||
], | ||
[ | ||
types.identifier(String(fetchBaseUrl)), | ||
...(routeType === 'static' ? [] : [types.identifier(String(resourceRoute))]), | ||
] | ||
) | ||
} | ||
const resolveResourceValue = (value: UIDLStaticValue | UIDLENVValue) => { | ||
if (!value) { | ||
return '' | ||
} | ||
if (value.type === 'static') { | ||
return value.content | ||
} | ||
return `process.env.${value.content}` | ||
} | ||
export const resolveObjectValue = (prop: UIDLStaticValue | UIDLPropValue | UIDLExpressionValue) => { | ||
if (prop.type === 'expr') { | ||
return types.identifier(prop.content) | ||
} | ||
const value = | ||
typeof prop.content === 'string' | ||
? types.stringLiteral(prop.content) | ||
: typeof prop.content === 'boolean' | ||
? types.booleanLiteral(prop.content) | ||
: typeof prop.content === 'number' | ||
? types.numericLiteral(prop.content) | ||
: typeof prop.content === 'object' | ||
? objectToObjectExpression(prop.content as unknown as Record<string, unknown>) | ||
: types.identifier(String(prop.content)) | ||
return value | ||
} | ||
export const getExpressionFromUIDLExpressionNode = ( | ||
node: UIDLExpressionValue | ||
): types.Expression => { | ||
const ast = parse(node.content, { | ||
sourceType: 'module' as const, | ||
}) | ||
if (!('program' in ast)) { | ||
throw new Error( | ||
`The AST does not have a program node in the expression inside addDynamicExpressionAttributeToJSXTag` | ||
) | ||
} | ||
const theStatementOnlyWihtoutTheProgram = ast.program.body[0] | ||
if (theStatementOnlyWihtoutTheProgram.type !== 'ExpressionStatement') { | ||
throw new Error(`Expr dynamic attribute only support expressions statements at the moment.`) | ||
} | ||
return theStatementOnlyWihtoutTheProgram.expression | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
477797
6325