Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"UI-WELCOME_MESSAGE": "Cargando Kibana",
"UI-WELCOME_ERROR": "Kibana no se cargó correctamente. Heck la salida del servidor para obtener más información."
}
"common.ui.welcomeMessage": "Cargando Kibana",
"common.ui.welcomeError": "Kibana no se cargó correctamente. Heck la salida del servidor para obtener más información."
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"UI-WELCOME_MESSAGE": "Cargando Kibana",
"UI-WELCOME_ERROR": "Kibana no se cargó correctamente. Heck la salida del servidor para obtener más información."
}
"common.ui.welcomeMessage": "Cargando Kibana",
"common.ui.welcomeError": "Kibana no se cargó correctamente. Heck la salida del servidor para obtener más información."
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"UI-WELCOME_MESSAGE": "Cargando Kibana",
"UI-WELCOME_ERROR": "Kibana no se cargó correctamente. Heck la salida del servidor para obtener más información."
}
"common.ui.welcomeMessage": "Cargando Kibana",
"common.ui.welcomeError": "Kibana no se cargó correctamente. Heck la salida del servidor para obtener más información."
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@
*/

require('../src/setup_node_env');
require('../src/dev/run_extract_default_translations');
require('../src/dev/run_i18n_check');
4 changes: 2 additions & 2 deletions src/dev/i18n/__snapshots__/extract_code_messages.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ Array [
]
`;

exports[`extractCodeMessages throws on empty id 1`] = `"Empty \\"id\\" value in i18n() or i18n.translate() is not allowed."`;
exports[`extractCodeMessages throws on empty id 1`] = `" I18N ERROR  Empty \\"id\\" value in i18n() or i18n.translate() is not allowed."`;

exports[`extractCodeMessages throws on missing defaultMessage 1`] = `"Empty defaultMessage in intl.formatMessage() is not allowed (\\"message-id\\")."`;
exports[`extractCodeMessages throws on missing defaultMessage 1`] = `" I18N ERROR  Empty defaultMessage in intl.formatMessage() is not allowed (\\"message-id\\")."`;
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,10 @@ exports[`dev/i18n/extract_default_translations injects default formats into en.j
}"
`;

exports[`dev/i18n/extract_default_translations throws on wrong message namespace 1`] = `"Expected \\"wrong_plugin_namespace.message-id\\" id to have \\"plugin_2\\" namespace. See i18nrc.json for the list of supported namespaces."`;
exports[`dev/i18n/extract_default_translations throws on id collision 1`] = `
" I18N ERROR  Error in src/dev/i18n/__fixtures__/extract_default_translations/test_plugin_3/test_file.jsx
Error:  I18N ERROR  There is more than one default message for the same id \\"plugin_3.duplicate_id\\":
\\"Message 1\\" and \\"Message 2\\""
`;

exports[`dev/i18n/extract_default_translations throws on wrong message namespace 1`] = `" I18N ERROR  Expected \\"wrong_plugin_namespace.message-id\\" id to have \\"plugin_2\\" namespace. See i18nrc.json for the list of supported namespaces."`;
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ Array [
]
`;

exports[`dev/i18n/extract_handlebars_messages throws on empty id 1`] = `"Empty id argument in Handlebars i18n is not allowed."`;
exports[`dev/i18n/extract_handlebars_messages throws on empty id 1`] = `" I18N ERROR  Empty id argument in Handlebars i18n is not allowed."`;

exports[`dev/i18n/extract_handlebars_messages throws on missing defaultMessage property 1`] = `"Empty defaultMessage in Handlebars i18n is not allowed (\\"message-id\\")."`;
exports[`dev/i18n/extract_handlebars_messages throws on missing defaultMessage property 1`] = `" I18N ERROR  Empty defaultMessage in Handlebars i18n is not allowed (\\"message-id\\")."`;

exports[`dev/i18n/extract_handlebars_messages throws on wrong number of arguments 1`] = `"Wrong number of arguments for handlebars i18n call."`;
exports[`dev/i18n/extract_handlebars_messages throws on wrong number of arguments 1`] = `" I18N ERROR  Wrong number of arguments for handlebars i18n call."`;

exports[`dev/i18n/extract_handlebars_messages throws on wrong properties argument type 1`] = `"Properties string in Handlebars i18n should be a string literal (\\"ui.id-1\\")."`;
exports[`dev/i18n/extract_handlebars_messages throws on wrong properties argument type 1`] = `" I18N ERROR  Properties string in Handlebars i18n should be a string literal (\\"ui.id-1\\")."`;
4 changes: 2 additions & 2 deletions src/dev/i18n/__snapshots__/extract_html_messages.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ Array [
]
`;

exports[`dev/i18n/extract_html_messages throws on empty i18n-id 1`] = `"Empty \\"i18n-id\\" value in angular directive is not allowed."`;
exports[`dev/i18n/extract_html_messages throws on empty i18n-id 1`] = `" I18N ERROR  Empty \\"i18n-id\\" value in angular directive is not allowed."`;

exports[`dev/i18n/extract_html_messages throws on missing i18n-default-message attribute 1`] = `"Empty defaultMessage in angular directive is not allowed (\\"message-id\\")."`;
exports[`dev/i18n/extract_html_messages throws on missing i18n-default-message attribute 1`] = `" I18N ERROR  Empty defaultMessage in angular directive is not allowed (\\"message-id\\")."`;
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ Array [
]
`;

exports[`extractI18nCallMessages throws if defaultMessage is not a string literal 1`] = `"defaultMessage value in i18n() or i18n.translate() should be a string literal (\\"message-id\\")."`;
exports[`extractI18nCallMessages throws if defaultMessage is not a string literal 1`] = `"[37m[41m I18N ERROR [49m[39m defaultMessage value in i18n() or i18n.translate() should be a string literal (\\"message-id\\")."`;

exports[`extractI18nCallMessages throws if message id value is not a string literal 1`] = `"Message id in i18n() or i18n.translate() should be a string literal."`;
exports[`extractI18nCallMessages throws if message id value is not a string literal 1`] = `"[37m[41m I18N ERROR [49m[39m Message id in i18n() or i18n.translate() should be a string literal."`;

exports[`extractI18nCallMessages throws if properties object is not provided 1`] = `"Empty defaultMessage in i18n() or i18n.translate() is not allowed (\\"message-id\\")."`;
exports[`extractI18nCallMessages throws if properties object is not provided 1`] = `"[37m[41m I18N ERROR [49m[39m Empty defaultMessage in i18n() or i18n.translate() is not allowed (\\"message-id\\")."`;

exports[`extractI18nCallMessages throws on empty defaultMessage 1`] = `"Empty defaultMessage in i18n() or i18n.translate() is not allowed (\\"message-id\\")."`;
exports[`extractI18nCallMessages throws on empty defaultMessage 1`] = `"[37m[41m I18N ERROR [49m[39m Empty defaultMessage in i18n() or i18n.translate() is not allowed (\\"message-id\\")."`;
4 changes: 2 additions & 2 deletions src/dev/i18n/__snapshots__/extract_pug_messages.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ Array [
]
`;

exports[`extractPugMessages throws on empty id 1`] = `"Empty \\"id\\" value in i18n() or i18n.translate() is not allowed."`;
exports[`extractPugMessages throws on empty id 1`] = `" I18N ERROR  Empty \\"id\\" value in i18n() or i18n.translate() is not allowed."`;

exports[`extractPugMessages throws on missing default message 1`] = `"Empty defaultMessage in i18n() or i18n.translate() is not allowed (\\"message-id\\")."`;
exports[`extractPugMessages throws on missing default message 1`] = `" I18N ERROR  Empty defaultMessage in i18n() or i18n.translate() is not allowed (\\"message-id\\")."`;
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ Array [
]
`;
exports[`dev/i18n/extract_react_messages extractIntlMessages throws if context value is not a string literal 1`] = `"context value should be a string literal (\\"message-id\\")."`;
exports[`dev/i18n/extract_react_messages extractIntlMessages throws if context value is not a string literal 1`] = `"[37m[41m I18N ERROR [49m[39m context value should be a string literal (\\"message-id\\")."`;
exports[`dev/i18n/extract_react_messages extractIntlMessages throws if defaultMessage value is not a string literal 1`] = `"defaultMessage value should be a string literal (\\"message-id\\")."`;
exports[`dev/i18n/extract_react_messages extractIntlMessages throws if defaultMessage value is not a string literal 1`] = `"[37m[41m I18N ERROR [49m[39m defaultMessage value should be a string literal (\\"message-id\\")."`;
exports[`dev/i18n/extract_react_messages extractIntlMessages throws if message id is not a string literal 1`] = `"Message id should be a string literal."`;
exports[`dev/i18n/extract_react_messages extractIntlMessages throws if message id is not a string literal 1`] = `"[37m[41m I18N ERROR [49m[39m Message id should be a string literal."`;
16 changes: 10 additions & 6 deletions src/dev/i18n/extract_default_translations.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,24 @@ import path from 'path';
import { i18n } from '@kbn/i18n';
import JSON5 from 'json5';
import normalize from 'normalize-path';
import chalk from 'chalk';

import { extractHtmlMessages } from './extract_html_messages';
import { extractCodeMessages } from './extract_code_messages';
import { extractPugMessages } from './extract_pug_messages';
import { extractHandlebarsMessages } from './extract_handlebars_messages';
import { globAsync, readFileAsync, writeFileAsync } from './utils';
import { paths, exclude } from '../../../.i18nrc.json';
import { createFailError } from '../run';

const ESCAPE_SINGLE_QUOTE_REGEX = /\\([\s\S])|(')/g;

function addMessageToMap(targetMap, key, value) {
const existingValue = targetMap.get(key);
if (targetMap.has(key) && existingValue.message !== value.message) {
throw new Error(
`There is more than one default message for the same id "${key}": \
"${existingValue.message}" and "${value.message}"`
);
throw createFailError(`${chalk.white.bgRed(' I18N ERROR ')} \
There is more than one default message for the same id "${key}":
"${existingValue.message}" and "${value.message}"`);
}
targetMap.set(key, value);
}
Expand Down Expand Up @@ -78,7 +79,8 @@ export function validateMessageNamespace(id, filePath) {
);

if (!id.startsWith(`${expectedNamespace}.`)) {
throw new Error(`Expected "${id}" id to have "${expectedNamespace}" namespace. \
throw createFailError(`${chalk.white.bgRed(' I18N ERROR ')} \
Expected "${id}" id to have "${expectedNamespace}" namespace. \
See i18nrc.json for the list of supported namespaces.`);
}
}
Expand Down Expand Up @@ -131,7 +133,9 @@ export async function extractMessagesFromPathToMap(inputPath, targetMap) {
addMessageToMap(targetMap, id, value);
}
} catch (error) {
throw new Error(`Error in ${name}\n${error.message || error}`);
throw createFailError(
`${chalk.white.bgRed(' I18N ERROR ')} Error in ${normalizePath(name)}\n${error}`
);
}
}
})
Expand Down
5 changes: 1 addition & 4 deletions src/dev/i18n/extract_default_translations.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,7 @@ describe('dev/i18n/extract_default_translations', () => {
const [, , pluginPath] = pluginsPaths;
await expect(
extractDefaultTranslations({ paths: [pluginPath], output: pluginPath })
).rejects.toMatchObject({
message: `Error in ${path.join(pluginPath, 'test_file.jsx')}
There is more than one default message for the same id "plugin_3.duplicate_id": "Message 1" and "Message 2"`,
});
).rejects.toThrowErrorMatchingSnapshot();
});

test('validates message namespace', () => {
Expand Down
35 changes: 26 additions & 9 deletions src/dev/i18n/extract_handlebars_messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@
* under the License.
*/

import chalk from 'chalk';

import { formatJSString } from './utils';
import { createFailError } from '../run';

const HBS_REGEX = /(?<=\{\{)([\s\S]*?)(?=\}\})/g;
const TOKENS_REGEX = /[^'\s]+|(?:'([^'\\]|\\[\s\S])*')/g;
Expand All @@ -36,42 +39,56 @@ export function* extractHandlebarsMessages(buffer) {
}

if (tokens.length !== 3) {
throw new Error('Wrong number of arguments for handlebars i18n call.');
throw createFailError(
`${chalk.white.bgRed(' I18N ERROR ')} Wrong number of arguments for handlebars i18n call.`
);
}

if (!idString.startsWith(`'`) || !idString.endsWith(`'`)) {
throw new Error('Message id should be a string literal.');
throw createFailError(
`${chalk.white.bgRed(' I18N ERROR ')} Message id should be a string literal.`
);
}

const messageId = formatJSString(idString.slice(1, -1));

if (!messageId) {
throw new Error(`Empty id argument in Handlebars i18n is not allowed.`);
throw createFailError(
`${chalk.white.bgRed(' I18N ERROR ')} Empty id argument in Handlebars i18n is not allowed.`
);
}

if (!propertiesString.startsWith(`'`) || !propertiesString.endsWith(`'`)) {
throw new Error(
`Properties string in Handlebars i18n should be a string literal ("${messageId}").`
throw createFailError(
`${chalk.white.bgRed(' I18N ERROR ')} \
Properties string in Handlebars i18n should be a string literal ("${messageId}").`
);
}

const properties = JSON.parse(propertiesString.slice(1, -1));
const message = formatJSString(properties.defaultMessage);

if (typeof message !== 'string') {
throw new Error(
`defaultMessage value in Handlebars i18n should be a string ("${messageId}").`
throw createFailError(
`${chalk.white.bgRed(' I18N ERROR ')} \
defaultMessage value in Handlebars i18n should be a string ("${messageId}").`
);
}

if (!message) {
throw new Error(`Empty defaultMessage in Handlebars i18n is not allowed ("${messageId}").`);
throw createFailError(
`${chalk.white.bgRed(' I18N ERROR ')} \
Empty defaultMessage in Handlebars i18n is not allowed ("${messageId}").`
);
}

const context = formatJSString(properties.context);

if (context != null && typeof context !== 'string') {
throw new Error(`Context value in Handlebars i18n should be a string ("${messageId}").`);
throw createFailError(
`${chalk.white.bgRed(' I18N ERROR ')} \
Context value in Handlebars i18n should be a string ("${messageId}").`
);
}

yield [messageId, { message, context }];
Expand Down
35 changes: 27 additions & 8 deletions src/dev/i18n/extract_html_messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@
* under the License.
*/

import chalk from 'chalk';
import { jsdom } from 'jsdom';
import { parse } from '@babel/parser';
import { isDirectiveLiteral, isObjectExpression, isStringLiteral } from '@babel/types';

import { isPropertyWithKey, formatHTMLString, formatJSString, traverseNodes } from './utils';
import { DEFAULT_MESSAGE_KEY, CONTEXT_KEY } from './constants';
import { createFailError } from '../run';

/**
* Find all substrings of "{{ any text }}" pattern
Expand Down Expand Up @@ -51,13 +53,17 @@ function parseFilterObjectExpression(expression) {
for (const property of node.properties) {
if (isPropertyWithKey(property, DEFAULT_MESSAGE_KEY)) {
if (!isStringLiteral(property.value)) {
throw new Error('defaultMessage value should be a string literal.');
throw createFailError(
`${chalk.white.bgRed(' I18N ERROR ')} defaultMessage value should be a string literal.`
);
}

message = formatJSString(property.value.value);
} else if (isPropertyWithKey(property, CONTEXT_KEY)) {
if (!isStringLiteral(property.value)) {
throw new Error('context value should be a string literal.');
throw createFailError(
`${chalk.white.bgRed(' I18N ERROR ')} context value should be a string literal.`
);
}

context = formatJSString(property.value.value);
Expand Down Expand Up @@ -95,20 +101,27 @@ function* getFilterMessages(htmlContent) {
const filterObjectExpression = expression.slice(filterStart + I18N_FILTER_MARKER.length).trim();

if (!filterObjectExpression || !idExpression) {
throw new Error(`Cannot parse i18n filter expression: {{ ${expression} }}`);
throw createFailError(
`${chalk.white.bgRed(' I18N ERROR ')} \
Cannot parse i18n filter expression: {{ ${expression} }}`
);
}

const messageId = parseIdExpression(idExpression);

if (!messageId) {
throw new Error('Empty "id" value in angular filter expression is not allowed.');
throw createFailError(
`${chalk.white.bgRed(' I18N ERROR ')} \
Empty "id" value in angular filter expression is not allowed.`
);
}

const { message, context } = parseFilterObjectExpression(filterObjectExpression) || {};

if (!message) {
throw new Error(
`Empty defaultMessage in angular filter expression is not allowed ("${messageId}").`
throw createFailError(
`${chalk.white.bgRed(' I18N ERROR ')} \
Empty defaultMessage in angular filter expression is not allowed ("${messageId}").`
);
}

Expand All @@ -124,12 +137,18 @@ function* getDirectiveMessages(htmlContent) {
for (const element of document.querySelectorAll('[i18n-id]')) {
const messageId = formatHTMLString(element.getAttribute('i18n-id'));
if (!messageId) {
throw new Error('Empty "i18n-id" value in angular directive is not allowed.');
throw createFailError(
`${chalk.white.bgRed(' I18N ERROR ')} \
Empty "i18n-id" value in angular directive is not allowed.`
);
}

const message = formatHTMLString(element.getAttribute('i18n-default-message'));
if (!message) {
throw new Error(`Empty defaultMessage in angular directive is not allowed ("${messageId}").`);
throw createFailError(
`${chalk.white.bgRed(' I18N ERROR ')} \
Empty defaultMessage in angular directive is not allowed ("${messageId}").`
);
}

const context = formatHTMLString(element.getAttribute('i18n-context')) || undefined;
Expand Down
Loading