* [Tools] Fix js multiline parsing in angular expressions * Add test
This commit is contained in:
parent
03b6de2b10
commit
99a8488f8b
|
@ -6,7 +6,7 @@ Array [
|
|||
"kbn.dashboard.id-1",
|
||||
Object {
|
||||
"context": "Message context 1",
|
||||
"message": "Message text 1",
|
||||
"message": "Message text 1 {value}",
|
||||
},
|
||||
],
|
||||
Array [
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
import cheerio from 'cheerio';
|
||||
import { parse } from '@babel/parser';
|
||||
import { isDirectiveLiteral, isObjectExpression } from '@babel/types';
|
||||
import { isObjectExpression, isStringLiteral } from '@babel/types';
|
||||
|
||||
import {
|
||||
isPropertyWithKey,
|
||||
|
@ -42,8 +42,24 @@ import { createFailError } from '../../run';
|
|||
*/
|
||||
const ANGULAR_EXPRESSION_REGEX = /{{([^{}]|({([^']|('([^']|(\\'))*'))*?}))*}}+/g;
|
||||
|
||||
const LINEBREAK_REGEX = /\n/g;
|
||||
const I18N_FILTER_MARKER = '| i18n: ';
|
||||
|
||||
function parseExpression(expression) {
|
||||
let ast;
|
||||
|
||||
try {
|
||||
ast = parse(`+${expression}`.replace(LINEBREAK_REGEX, ' '));
|
||||
} catch (error) {
|
||||
if (error instanceof SyntaxError) {
|
||||
const errorWithContext = createParserErrorMessage(` ${expression}`, error);
|
||||
throw createFailError(`Couldn't parse angular i18n expression:\n${errorWithContext}`);
|
||||
}
|
||||
}
|
||||
|
||||
return ast;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract default message from an angular filter expression argument
|
||||
* @param {string} expression JavaScript code containing a filter object
|
||||
|
@ -51,22 +67,7 @@ const I18N_FILTER_MARKER = '| i18n: ';
|
|||
* @returns {{ message?: string, context?: string, valuesKeys: string[]] }}
|
||||
*/
|
||||
function parseFilterObjectExpression(expression, messageId) {
|
||||
let ast;
|
||||
|
||||
try {
|
||||
// parse an object expression instead of block statement
|
||||
ast = parse(`+${expression}`);
|
||||
} catch (error) {
|
||||
if (error instanceof SyntaxError) {
|
||||
const errorWithContext = createParserErrorMessage(` ${expression}`, error);
|
||||
throw createFailError(
|
||||
`Couldn't parse angular expression with i18n filter:\n${errorWithContext}`
|
||||
);
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
|
||||
const ast = parseExpression(expression);
|
||||
const objectExpressionNode = [...traverseNodes(ast.program.body)].find(node =>
|
||||
isObjectExpression(node)
|
||||
);
|
||||
|
@ -97,30 +98,14 @@ function parseFilterObjectExpression(expression, messageId) {
|
|||
}
|
||||
|
||||
function parseIdExpression(expression) {
|
||||
let ast;
|
||||
|
||||
try {
|
||||
ast = parse(expression);
|
||||
} catch (error) {
|
||||
if (error instanceof SyntaxError) {
|
||||
const errorWithContext = createParserErrorMessage(expression, error);
|
||||
throw createFailError(
|
||||
`Couldn't parse angular expression with i18n filter:\n${errorWithContext}`
|
||||
);
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
|
||||
const stringNode = [...traverseNodes(ast.program.directives)].find(node =>
|
||||
isDirectiveLiteral(node)
|
||||
);
|
||||
const ast = parseExpression(expression);
|
||||
const stringNode = [...traverseNodes(ast.program.body)].find(node => isStringLiteral(node));
|
||||
|
||||
if (!stringNode) {
|
||||
throw createFailError(`Message id should be a string literal, but got: \n${expression}`);
|
||||
}
|
||||
|
||||
return formatJSString(stringNode.value);
|
||||
return stringNode ? formatJSString(stringNode.value) : null;
|
||||
}
|
||||
|
||||
function trimCurlyBraces(string) {
|
||||
|
@ -257,8 +242,10 @@ function* getDirectiveMessages(htmlContent) {
|
|||
}
|
||||
|
||||
if (element.values) {
|
||||
const nodes = parse(`+${element.values}`).program.body;
|
||||
const valuesObjectNode = [...traverseNodes(nodes)].find(node => isObjectExpression(node));
|
||||
const ast = parseExpression(element.values);
|
||||
const valuesObjectNode = [...traverseNodes(ast.program.body)].find(node =>
|
||||
isObjectExpression(node)
|
||||
);
|
||||
const valuesKeys = extractValuesKeysFromNode(valuesObjectNode);
|
||||
|
||||
checkValuesProperty(valuesKeys, message, messageId);
|
||||
|
|
|
@ -24,8 +24,12 @@ const htmlSourceBuffer = Buffer.from(`
|
|||
<div>
|
||||
<p
|
||||
i18n-id="kbn.dashboard.id-1"
|
||||
i18n-default-message="Message text 1"
|
||||
i18n-default-message="Message text 1 {value}"
|
||||
i18n-context="Message context 1"
|
||||
i18n-values="{
|
||||
value: 'Multiline
|
||||
string',
|
||||
}"
|
||||
></p>
|
||||
</div>
|
||||
<div>
|
||||
|
|
Loading…
Reference in a new issue