fix(validator): allow using question mask in expression

This commit is contained in:
Bowen Tan 2022-07-27 10:31:25 +08:00
parent d21e1526f6
commit cf62b867ba
3 changed files with 34 additions and 10 deletions

View File

@ -20,12 +20,21 @@ describe('Field test', () => {
'value',
]);
expect(field.refComponentInfos['list' as ComponentId].refProperties).toEqual([
'[0]',
'[0].text',
'0',
'0.text',
]);
expect(field.rawValue).toEqual('{{input.value}} + {{list[0].text}}');
});
it('allow using question mask in expression', () => {
const field = new FieldModel('{{api.fetch?.data }}');
expect(field.isDynamic).toEqual(true);
expect(field.refComponentInfos['api' as ComponentId].refProperties).toEqual([
'fetch',
'fetch.data',
]);
});
it('parse inline variable in expression', () => {
const field = new FieldModel('{{ [].length }}');
expect(field.isDynamic).toEqual(true);

View File

@ -21,6 +21,11 @@ import { JSONSchema7 } from 'json-schema';
export type FunctionNode = ASTNode & { params: ASTNode[] };
export type DeclaratorNode = ASTNode & { id: ASTNode };
export type LiteralNode = ASTNode & { raw: string };
export type ExpressionNode = ASTNode & {
object: ExpressionNode;
property: ExpressionNode | LiteralNode;
};
export class FieldModel implements IFieldModel {
isDynamic = false;
refComponentInfos: Record<ComponentId | ModuleId, RefInfo> = {};
@ -191,12 +196,9 @@ export class FieldModel implements IFieldModel {
break;
case 'MemberExpression':
const str = exp.slice(expressionNode.start, expressionNode.end);
let path = str.replace(lastIdentifier, '');
if (path.startsWith('.')) {
path = path.slice(1, path.length);
}
this.refComponentInfos[lastIdentifier]?.refProperties.push(path);
this.refComponentInfos[lastIdentifier]?.refProperties.push(
this.genPathFromMemberExpressionNode(expressionNode as ExpressionNode)
);
break;
default:
}
@ -205,7 +207,6 @@ export class FieldModel implements IFieldModel {
localVariables.push((declarator as DeclaratorNode).id);
},
});
// remove localVariables from refs
for (const key in this.refComponentInfos) {
if (localVariables.some(({ name }) => key === name)) {
@ -215,6 +216,21 @@ export class FieldModel implements IFieldModel {
});
}
private genPathFromMemberExpressionNode(expNode: ExpressionNode) {
const path: string[] = [];
function travel(node: ExpressionNode) {
path.unshift(
node.property?.name || (node.property as LiteralNode)?.raw || node.name
);
if (node.object) {
travel(node.object);
}
}
travel(expNode);
return path.slice(1).join('.');
}
private onReferenceIdChange({ oldId, newId }: AppModelEventType['idChange']) {
if (!this.componentModel) {
return;

View File

@ -73,7 +73,6 @@ export function generateDefaultValueFromSpec(
}
// It is any type
console.log('any', returnPlaceholderForAny);
if (returnPlaceholderForAny) {
return AnyTypePlaceholder;
}