Socket
Socket
Sign inDemoInstall

@lingui/macro

Package Overview
Dependencies
Maintainers
1
Versions
115
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@lingui/macro - npm Package Compare versions

Comparing version 2.7.0 to 3.0.0-1

jsx.js

95

index.js
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.number = exports.date = exports.selectOrdinal = exports.select = exports.plural = exports.t = exports.NumberFormat = exports.DateFormat = exports.SelectOrdinal = exports.Select = exports.Plural = exports.Trans = undefined;
exports.default = exports.number = exports.date = exports.selectOrdinal = exports.select = exports.plural = exports.t = exports.NumberFormat = exports.DateFormat = exports.SelectOrdinal = exports.Select = exports.Plural = exports.Trans = void 0;
var _keys = require("babel-runtime/core-js/object/keys");
var _keys2 = _interopRequireDefault(_keys);
var _babelPluginMacros = require("babel-plugin-macros");
var _js = require("./js");
var _js = _interopRequireDefault(require("./js"));
var _js2 = _interopRequireDefault(_js);
var _jsx = _interopRequireDefault(require("./jsx"));
var _transformer = require("@lingui/babel-plugin-transform-react/transformer");
var _transformer2 = _interopRequireDefault(_transformer);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function macro(_ref) {

@@ -29,10 +21,7 @@ var references = _ref.references,

var t = babel.types;
var transformer = (0, _js2.default)(babel);
var jsxTransformer = new _transformer2.default(babel);
var transformer = (0, _js.default)(babel);
var jsxTransformer = new _jsx.default(babel);
var reactImportsToCarryOver = ["DateFormat", "NumberFormat"];
var reactImports = [];
(0, _keys2.default)(references).forEach(function (tagName) {
Object.keys(references).forEach(function (tagName) {
var tags = references[tagName];

@@ -48,10 +37,9 @@ var macroType = getMacroType(tagName);

reactImports.push(tagName);
}
} // Trick the plugin into thinking we've processed an import
// Trick the plugin into thinking we've processed an import
jsxTransformer.setImportDeclarations((0, _keys2.default)(references).reduce(function (obj, key) {
jsxTransformer.setImportDeclarations(Object.keys(references).reduce(function (obj, key) {
if (key !== "default" || key !== "Trans") obj[key] = key;
return obj;
}, {}));
tags.forEach(function (openingTag) {

@@ -61,4 +49,5 @@ if (!t.isJSXOpeningElement(openingTag.container)) return; // Exclude closing elements

var node = openingTag.context.parentPath.container;
jsxTransformer.transform({ node: node }, state.file);
jsxTransformer.transform({
node: node
}, state.file);
});

@@ -77,3 +66,2 @@ } else {

});
addLinguiReactImports(babel, state, reactImports);

@@ -97,2 +85,3 @@

return "js";
case "Trans":

@@ -110,11 +99,7 @@ case "Plural":

if (!imports.length) return;
var t = babel.types;
var linguiReactImport = state.file.path.node.body.find(function (importNode) {
return t.isImportDeclaration(importNode) && importNode.source.value === "@lingui/react";
});
}); // Handle adding the import or altering the existing import
// Handle adding the import or altering the existing import
if (linguiReactImport) {

@@ -136,27 +121,51 @@ imports.forEach(function (name) {

var Trans = function Trans() {};
exports.Trans = Trans;
var Plural = function Plural() {};
exports.Plural = Plural;
var Select = function Select() {};
exports.Select = Select;
var SelectOrdinal = function SelectOrdinal() {};
exports.SelectOrdinal = SelectOrdinal;
var DateFormat = function DateFormat() {};
exports.DateFormat = DateFormat;
var NumberFormat = function NumberFormat() {};
exports.NumberFormat = NumberFormat;
var t = function t() {};
exports.t = t;
var plural = function plural() {};
exports.plural = plural;
var select = function select() {};
exports.select = select;
var selectOrdinal = function selectOrdinal() {};
exports.selectOrdinal = selectOrdinal;
var date = function date() {};
exports.date = date;
var number = function number() {};
exports.Trans = Trans;
exports.Plural = Plural;
exports.Select = Select;
exports.SelectOrdinal = SelectOrdinal;
exports.DateFormat = DateFormat;
exports.NumberFormat = NumberFormat;
exports.t = t;
exports.plural = plural;
exports.select = select;
exports.selectOrdinal = selectOrdinal;
exports.date = date;
exports.number = number;
exports.default = (0, _babelPluginMacros.createMacro)(macro);
var _default = (0, _babelPluginMacros.createMacro)(macro);
exports.default = _default;
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = _default;
var _values = require("babel-runtime/core-js/object/values");
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread"));
var _values2 = _interopRequireDefault(_values);
var _validation = require("./validation");
var _getIterator2 = require("babel-runtime/core-js/get-iterator");
var keepSpaceRe = /(?:\\(?:\r\n|\r|\n))+\s+/g;
var keepNewLineRe = /(?:\r\n|\r|\n)+\s+/g;
var _getIterator3 = _interopRequireDefault(_getIterator2);
var generatorFactory = function generatorFactory() {
var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
return function () {
return index++;
};
};
var _includes = require("babel-runtime/core-js/array/includes");
function normalizeWhitespace(text) {
return text.replace(keepSpaceRe, " ").replace(keepNewLineRe, "\n").trim();
}
var _includes2 = _interopRequireDefault(_includes);
function _default(_ref) {
var t = _ref.types;
var _keys = require("babel-runtime/core-js/object/keys");
/**
* `transform` is the macro entry point. It takes matched AST node (`path`) and
* reference to `file` being processed.
*/
function transform(path, file) {
var initialProps = {
text: "",
values: {},
formats: {},
argumentGenerator: generatorFactory() // 1. Transform template string literals and i18n methods to ICU Message Format
var _keys2 = _interopRequireDefault(_keys);
};
var props = transformNode(path.node, file, initialProps, true);
props.text = normalizeWhitespace(props.text);
if (!props.text) return; // 2. Create message descriptor
var _extends2 = require("babel-runtime/helpers/extends");
var exp = createMessageDescriptor(props); // 3. Copy source line info
var _extends3 = _interopRequireDefault(_extends2);
exp.loc = path.node.loc;
path.replaceWith(exp); // 4. Add leading `i18n` comment (if doesn't exist) for lingui-extract
exports.default = function (_ref) {
var t = _ref.types;
var nodeWithComments = path.parentPath.type === "ExpressionStatement" ? path.parentPath.node : path.node;
var i18nComment = nodeWithComments.leadingComments && nodeWithComments.leadingComments.filter(function (node) {
return node.value.trim().substr(0, 4) === "i18n";
})[0];
var isIdentifier = function isIdentifier(node, name) {
return t.isIdentifier(node, { name: name });
};
if (!i18nComment) {
path.addComment("leading", "i18n");
}
}
var isI18nMethod = function isI18nMethod(node) {
return isIdentifier(node.tag, "t") || t.isCallExpression(node.tag) && isIdentifier(node.tag.callee, "t");
};
function transformNode(node, file, props) {
var root = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
var isChoiceMethod = function isChoiceMethod(node) {
return isIdentifier(node, "plural") || isIdentifier(node, "select") || isIdentifier(node, "selectOrdinal");
};
if (isI18nMethod(node)) {
// t
return transformTemplateTag(node, file, props);
} else if (isChoiceMethod(node.callee)) {
// plural, select and selectOrdinal
return transformChoiceMethod(node, file, props, root);
} else if (isFormatMethod(node.callee)) {
// date, number
return transformFormatMethod(node, file, props, root);
}
var isFormatMethod = function isFormatMethod(node) {
return isIdentifier(node, "date") || isIdentifier(node, "number");
};
return props;
}
/**
* Convert identifiers to *named* arguments and everything else
* to *positional* arguments.
* Once we transform macro, we have an object with message props:
* - text: this will become msg ID
* - defaults: defualt message if custom message ID is used
* - values: variables and values
* - formats: date/number formats
*
* Example
* `world` is named argument and `new Date()` is positional one
*
* Input: `Hello ${world}, today is ${new Date()}`
* Output: `Hello {world}, today is {0}`
* This object is transformed to *message descriptor*, an object passed to `i18n._`
* method which performs translation and formatting.
*/
function expressionToArgument(exp, props) {
var name = t.isIdentifier(exp) ? exp.name : props.argumentGenerator();
var key = t.isIdentifier(exp) ? exp : t.numericLiteral(name);
return { name: name, key: key };
function createMessageDescriptor(props) {
var descriptor = [t.objectProperty(t.identifier("id"), t.StringLiteral(props.text))];
if (props.defaults) {
descriptor.push(t.objectProperty(t.identifier("defaults"), t.stringLiteral(props.defaults)));
}
var formatsList = Object.values(props.formats);
if (formatsList.length) {
descriptor.push(t.objectProperty(t.identifier("formats"), t.objectExpression(formatsList)));
}
var valuesList = Object.values(props.values);
if (valuesList.length) {
descriptor.push(t.objectProperty(t.identifier("values"), t.objectExpression(valuesList.length ? valuesList : [])));
}
return t.objectExpression(descriptor);
}
function transformI18nMethod(node, file, props) {
if (t.isCallExpression(node.tag)) {
// Message with custom ID, where message is used as defaults
// i18n.t('id')`Hello World`
var defaults = node.tag.arguments[0];
if (!t.isStringLiteral(defaults)) {
throw file.buildCodeFrameError(node.tag, "Message ID must be a string");
}
var newProps = transformTemplateLiteral(node.quasi, file, props);
return (0, _extends3.default)({}, newProps, {
text: defaults.value,
defaults: props.text
});
function transformTemplateTag(node, file, props) {
var tag = node.tag,
quasi = node.quasi;
if (!t.isCallExpression(tag)) {
/**
* t`Message`
* Simple templatetag - generated message is used as an ID
*/
return transformTemplateLiteral(node.quasi, file, props);
}
/**
* t('id')`Message`
* Template tag with an argument - generated message is used as a default one
*/
return transformTemplateLiteral(node.quasi, file, props);
var msgId = tag.arguments[0];
if (!t.isStringLiteral(msgId)) {
// TODO: Add link to lazy translation in docs.
throw file.buildCodeFrameError(tag, "Message ID must be a string.");
}
var newProps = transformTemplateLiteral(quasi, file, props);
return (0, _objectSpread2.default)({}, newProps, {
text: msgId.value,
// FIXME: Why not newProps.text?
defaults: props.text
});
}
function transformTemplateLiteral(exp, file, props) {
var parts = [];
exp.quasis.forEach(function (item, index) {
parts.push(item);
if (!item.tail) parts.push(exp.expressions[index]);
});
parts.forEach(function (item) {
if (t.isTemplateElement(item)) {
props.text += item.value.raw;
} else if (t.isCallExpression(item) && (isI18nMethod(item.callee) || isChoiceMethod(item.callee) || isFormatMethod(item.callee))) {
var _transformNode = transformNode(item, file, (0, _objectSpread2.default)({}, props, {
text: ""
})),
text = _transformNode.text;
props.text += "{".concat(text, "}");
} else {
var _expressionToArgument = expressionToArgument(item, props),
name = _expressionToArgument.name,
key = _expressionToArgument.key;
props.text += "{".concat(name, "}");
props.values[name] = t.objectProperty(key, item);
}
});
return props;
}
function transformChoiceMethod(node, file, props) {
var root = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
var choices = {};
var choicesType = node.callee.name.toLowerCase();
var defaults = void 0;
var variable = void 0;
var defaults;
var variable;
var offset = "";
var choiceArguments = node.arguments[0];
var choiceArguments = node.arguments[0];
if (t.isStringLiteral(choiceArguments)) {

@@ -101,3 +191,3 @@ defaults = choiceArguments.value;

try {
for (var _iterator = (0, _getIterator3.default)(choiceArguments.properties), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
for (var _iterator = choiceArguments.properties[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var attr = _step.value;

@@ -109,4 +199,3 @@

var key = attr.key;
// key is either:
var key = attr.key; // key is either:
// NumericLiteral => convert to `={number}`

@@ -116,3 +205,3 @@ // StringLiteral => key.value

var name = t.isNumericLiteral(key) ? "=" + key.value : key.name || key.value;
var name = t.isNumericLiteral(key) ? "=".concat(key.value) : key.name || key.value;

@@ -122,5 +211,5 @@ if (name === "value") {

var _expressionToArgument = expressionToArgument(exp, props),
_name = _expressionToArgument.name,
_key = _expressionToArgument.key;
var _expressionToArgument2 = expressionToArgument(exp, props),
_name = _expressionToArgument2.name,
_key = _expressionToArgument2.key;

@@ -134,3 +223,4 @@ variable = _name;

}
offset = " offset:" + attr.value.value;
offset = " offset:".concat(attr.value.value);
} else {

@@ -140,3 +230,3 @@ var value = "";

if (t.isTemplateLiteral(attr.value)) {
props = transformTemplateLiteral(attr.value, file, (0, _extends3.default)({}, props, {
props = transformTemplateLiteral(attr.value, file, (0, _objectSpread2.default)({}, props, {
text: ""

@@ -146,3 +236,5 @@ }));

} else if (t.isCallExpression(attr.value)) {
props = transformMethod(attr.value, file, (0, _extends3.default)({}, props, { text: "" }));
props = transformNode(attr.value, file, (0, _objectSpread2.default)({}, props, {
text: ""
}));
value = props.text;

@@ -152,7 +244,7 @@ } else {

}
choices[name] = value;
}
}
} // missing value
// missing value
} catch (err) {

@@ -163,3 +255,3 @@ _didIteratorError = true;

try {
if (!_iteratorNormalCompletion && _iterator.return) {
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();

@@ -178,28 +270,14 @@ }

var choicesKeys = (0, _keys2.default)(choices);
// 'other' choice is required
if (!choicesKeys.length) {
throw file.buildCodeFrameError(node.callee, "Missing " + choicesType + " choices. At least fallback argument 'other' is required.");
} else if (!(0, _includes2.default)(choicesKeys, "other")) {
throw file.buildCodeFrameError(node.callee, "Missing fallback argument 'other'.");
}
// validate plural rules
if (choicesType === "plural" || choicesType === "selectordinal") {
choicesKeys.forEach(function (rule) {
if (!(0, _includes2.default)(pluralRules, rule) && !/=\d+/.test(rule)) {
throw file.buildCodeFrameError(node.callee, "Invalid plural rule '" + rule + "'. Must be " + pluralRules.join(", ") + " or exact number depending on your source language ('one' and 'other' for English).");
}
});
}
var choicesKeys = Object.keys(choices);
(0, _validation.validatePluralRules)(choicesType, choicesKeys, function (message) {
throw file.buildCodeFrameError(node.callee, message);
});
var argument = choicesKeys.map(function (form) {
return form + " {" + choices[form] + "}";
return "".concat(form, " {").concat(choices[form], "}");
}).join(" ");
var format = variable + ", " + choicesType + "," + offset + " " + argument;
props.text = root ? "{" + format + "}" : format;
var format = "".concat(variable, ", ").concat(choicesType, ",").concat(offset, " ").concat(argument);
props.text = root ? "{".concat(format, "}") : format;
if (defaults) {
return (0, _extends3.default)({}, props, {
return (0, _objectSpread2.default)({}, props, {
text: defaults,

@@ -214,5 +292,4 @@ defaults: props.text

function transformFormatMethod(node, file, props, root) {
var exp = node.arguments[0];
var exp = node.arguments[0]; // missing value
// missing value
if (exp === undefined) {

@@ -222,5 +299,5 @@ throw file.buildCodeFrameError(node.callee, "The first argument of format function must be a variable.");

var _expressionToArgument2 = expressionToArgument(exp, props),
name = _expressionToArgument2.name,
key = _expressionToArgument2.key;
var _expressionToArgument3 = expressionToArgument(exp, props),
name = _expressionToArgument3.name,
key = _expressionToArgument3.key;

@@ -231,7 +308,6 @@ var type = node.callee.name;

];
var format = "";
var formatArg = node.arguments[1];
if (!formatArg) {
// Do not throw validation error when format doesn't exist
if (!formatArg) {// Do not throw validation error when format doesn't exist
} else if (t.isStringLiteral(formatArg)) {

@@ -243,7 +319,7 @@ format = formatArg.value;

} else {
var formatName = new RegExp("^" + type + "\\d+$");
var existing = (0, _keys2.default)(props.formats).filter(function (name) {
var formatName = new RegExp("^".concat(type, "\\d+$"));
var existing = Object.keys(props.formats).filter(function (name) {
return formatName.test(name);
});
format = "" + type + (existing.length || 0);
format = "".concat(type).concat(existing.length || 0);
}

@@ -257,118 +333,49 @@

if (format) parts.push(format);
props.values[name] = t.objectProperty(key, exp);
props.text += "" + parts.join(",");
props.text += "".concat(parts.join(","));
return props;
}
/**
* Custom matchers
*/
function transformTemplateLiteral(exp, file, props) {
var parts = [];
exp.quasis.forEach(function (item, index) {
parts.push(item);
if (!item.tail) parts.push(exp.expressions[index]);
var isIdentifier = function isIdentifier(node, name) {
return t.isIdentifier(node, {
name: name
});
};
parts.forEach(function (item) {
if (t.isTemplateElement(item)) {
props.text += item.value.raw;
} else if (t.isCallExpression(item) && (isI18nMethod(item.callee) || isChoiceMethod(item.callee) || isFormatMethod(item.callee))) {
var _transformMethod = transformMethod(item, file, (0, _extends3.default)({}, props, {
text: ""
})),
text = _transformMethod.text;
var isI18nMethod = function isI18nMethod(node) {
return isIdentifier(node.tag, "t") || t.isCallExpression(node.tag) && isIdentifier(node.tag.callee, "t");
};
props.text += "{" + text + "}";
} else {
var _expressionToArgument3 = expressionToArgument(item, props),
name = _expressionToArgument3.name,
key = _expressionToArgument3.key;
var isChoiceMethod = function isChoiceMethod(node) {
return isIdentifier(node, "plural") || isIdentifier(node, "select") || isIdentifier(node, "selectOrdinal");
};
props.text += "{" + name + "}";
props.values[name] = t.objectProperty(key, item);
}
});
var isFormatMethod = function isFormatMethod(node) {
return isIdentifier(node, "date") || isIdentifier(node, "number");
};
/**
* Convert identifiers to *named* arguments and expressions to *positional* arguments.
*
* Example
* `world` is named argument and `new Date()` is positional one:
*
* Input: `Hello ${world}, today is ${new Date()}`
* Output: `Hello {world}, today is {0}`
*/
return props;
}
function transformMethod(node, file, props) {
var root = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
if (isI18nMethod(node)) {
// t
return transformI18nMethod(node, file, props);
} else if (isChoiceMethod(node.callee)) {
// plural, select and selectOrdinal
return transformChoiceMethod(node, file, props, root);
} else if (isFormatMethod(node.callee)) {
// date, number
return transformFormatMethod(node, file, props, root);
}
return props;
function expressionToArgument(exp, props) {
var name = t.isIdentifier(exp) ? exp.name : props.argumentGenerator();
var key = t.isIdentifier(exp) ? exp : t.numericLiteral(name);
return {
name: name,
key: key
};
}
return function transform(path, file) {
// 1. Collect all parameters and generate message ID
var props = transformMethod(path.node, file, initialProps(), true);
var text = props.text.replace(nlRe, " ").trim();
if (!text) return;
// 2. Create message descriptor
var descriptorProps = [t.objectProperty(t.identifier("id"), t.StringLiteral(text))];
if (props.defaults) {
descriptorProps.push(t.objectProperty(t.identifier("defaults"), t.stringLiteral(props.defaults)));
}
var formatsList = (0, _values2.default)(props.formats);
if (formatsList.length) {
descriptorProps.push(t.objectProperty(t.identifier("formats"), t.objectExpression(formatsList)));
}
var valuesList = (0, _values2.default)(props.values);
if (valuesList.length) {
descriptorProps.push(t.objectProperty(t.identifier("values"), t.objectExpression(valuesList.length ? valuesList : [])));
}
var exp = t.objectExpression(descriptorProps);
exp.loc = path.node.loc;
path.replaceWith(exp);
// 3. Add leading `i18n` comment (if doesn't exist) for lingui-extract
var nodeWithComments = path.parentPath.type === "ExpressionStatement" ? path.parentPath.node : path.node;
var i18nComment = nodeWithComments.leadingComments && nodeWithComments.leadingComments.filter(function (node) {
return node.value.trim().substr(0, 4) === "i18n";
})[0];
if (!i18nComment) {
path.addComment("leading", "i18n");
}
};
};
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var nlRe = /(?:\r\n|\r|\n)+\s+/g;
var pluralRules = ["zero", "one", "two", "few", "many", "other"];
var generatorFactory = function generatorFactory() {
var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
return function () {
return index++;
};
};
var initialProps = function initialProps() {
return {
text: "",
values: {},
formats: {},
argumentGenerator: generatorFactory()
};
};
return transform;
}
{
"name": "@lingui/macro",
"version": "2.7.0",
"version": "3.0.0-1",
"description": "Macro for generating messages in ICU MessageFormat syntax",

@@ -22,8 +22,7 @@ "main": "index.js",

"engines": {
"node": ">=6.0"
"node": ">=8.0.0"
},
"dependencies": {
"@lingui/babel-plugin-transform-react": "2.7.0",
"babel-plugin-macros": "^2.2.0"
"babel-plugin-macros": "^2.4.2"
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc