Skip to content

Commit

Permalink
Merge pull request #5 from lingui/improved-codemod
Browse files Browse the repository at this point in the history
fix: import date-number from i18n instance
  • Loading branch information
semoal authored Oct 28, 2020
2 parents 083d2b8 + 0f21a90 commit e6ecd7e
Show file tree
Hide file tree
Showing 10 changed files with 209 additions and 25 deletions.
5 changes: 3 additions & 2 deletions bin/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import path from 'path';
import execa from 'execa';
import chalk from 'chalk';
import isGitClean from 'is-git-clean';
import pkg from "../package.json";

const transformerDirectory = path.join(__dirname, '../', 'transforms');
const jscodeshiftExecutable = require.resolve('.bin/jscodeshift');
Expand Down Expand Up @@ -151,7 +152,7 @@ function expandFilePathsIfNeeded(filesBeforeExpansion) {
function run() {
const cli = meow(
{
description: 'Codemods for @lingui APIs.',
description: `Codemods for @lingui APIs. Version: ${pkg.version}`,
help: `
Usage
$ npx lingui-codemod <transform> <path> <...options>
Expand All @@ -166,7 +167,7 @@ function run() {
`
},
{
boolean: ['force', 'dry', 'print', 'remove-unused', 'help'],
boolean: ['force', 'dry', 'print', 'remove-unused-imports', 'help'],
string: ['_'],
alias: {
h: 'help'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
import { React } from "react";
import { t, date } from "@lingui/macro";
import { t, date } from "@lingui/macro";
import { Trans, NumberFormat, Plural } from "@lingui/react";
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import { React } from "react";
import { date } from "@lingui/core";
import { t } from "@lingui/macro";
import { i18n } from "@lingui/core";
import { t, Plural, Trans } from "@lingui/macro";
2 changes: 1 addition & 1 deletion transforms/__testfixtures__/v2-to-v3/complete.input.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from "react";
import { NumberFormat, DateFormat, Trans, withI18n } from "@lingui/react"
import { plural } from "@lingui/macro"

const App = ({ i18n }) => {
const App = () => {
return (
<div>
<div>
Expand Down
8 changes: 4 additions & 4 deletions transforms/__testfixtures__/v2-to-v3/complete.output.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import React from "react";
import { number, date } from "@lingui/core";
import { i18n } from "@lingui/core";
import { withI18n } from "@lingui/react";
import { plural, Trans } from "@lingui/macro";

const App = ({ i18n }) => {
const App = () => {
return (
<div>
<div>
{number(1_000_000, { currency: "EUR" })}
{i18n.number(1_000_000, { currency: "EUR" })}
</div>
<div>
{date(new Date(), { hour12: true })}
{i18n.date(new Date(), { hour12: true })}
</div>
<Trans>Component to replace</Trans>
{/* TODO: if there isn't any with children we should keep lingui/react */}
Expand Down
52 changes: 50 additions & 2 deletions transforms/__testfixtures__/v2-to-v3/jsxTransformMacros.input.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import React from "react";
import { DateFormat, NumberFormat } from "@lingui/react";
import { DateFormat, NumberFormat, Plural, SelectOrdinal, Select } from "@lingui/react";

const GLOBAL_VALUE = new Date();

const App = () => {
const count = 1;
return (
<div>
<DateFormat value={new Date()} format={{ hour12: true }} />
Expand All @@ -13,6 +15,52 @@ const App = () => {
style: "currency",
maximumFractionDigits: 2
}} />
{true ? (
<NumberFormat value={10} format={{
style: "currency",
maximumFractionDigits: 2
}} />
) : false}
<Plural
id="string"
value={100}
offset="number | string"
zero="ReactNode"
one="ReactNode"
two="ReactNode"
few="ReactNode"
many="ReactNode"
other="ReactNode"
_1="_1"
_2="_2"
/>
<SelectOrdinal
value={count}
one="#st"
two="#nd"
few="#rd"
other="#th"
/>
<Select
value={count}
male="His book"
female="Her book"
other="Their book"
/>
</div>
);
}
}

const formatfValue = (value) => {
return (
<NumberFormat value={10} format={{ style: "currency", maximumFractionDigits: 2 }} />
)
};

const formatAssetValue = (value) => {
if (value !== null) {
const formatValue = <NumberFormat value={value} format={{style: "percent", minimumFractionDigits: 2 }} />;
return formatValue;
}
return "-";
};
59 changes: 53 additions & 6 deletions transforms/__testfixtures__/v2-to-v3/jsxTransformMacros.output.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,65 @@
import React from "react";
import { number, date } from "@lingui/core";
import { i18n } from "@lingui/core";
import { Plural, Select, SelectOrdinal } from "@lingui/macro";

const GLOBAL_VALUE = new Date();

const App = () => {
const count = 1;
return (
<div>
{date(new Date(), { hour12: true })}
{date(new Date())}
{date(GLOBAL_VALUE)}
{date("10/01/2015")}
{number(10, {
{i18n.date(new Date(), { hour12: true })}
{i18n.date(new Date())}
{i18n.date(GLOBAL_VALUE)}
{i18n.date("10/01/2015")}
{i18n.number(10, {
style: "currency",
maximumFractionDigits: 2
})}
{true ? (
i18n.number(10, {
style: "currency",
maximumFractionDigits: 2
})
) : false}
<Plural
id="string"
value={100}
offset="number | string"
zero="ReactNode"
one="ReactNode"
two="ReactNode"
few="ReactNode"
many="ReactNode"
other="ReactNode"
_1="_1"
_2="_2"
/>
<SelectOrdinal
value={count}
one="#st"
two="#nd"
few="#rd"
other="#th"
/>
<Select
value={count}
male="His book"
female="Her book"
other="Their book"
/>
</div>
);
}

const formatfValue = (value) => {
return (i18n.number(10, { style: "currency", maximumFractionDigits: 2 }));
};

const formatAssetValue = (value) => {
if (value !== null) {
const formatValue = i18n.number(value, {style: "percent", minimumFractionDigits: 2 });
return formatValue;
}
return "-";
};
70 changes: 70 additions & 0 deletions transforms/legacy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/** This file has some functions that aren't used by could be used in the future */

/** Change JSX Elements to simple functions
* <Jsx value="hola" _1="hola" /> -> jsx(value, { _1: "hola" })
*/
function changeJsxPluralToMacro(root, j) {
[
{
component: 'Plural',
macro: 'plural',
},
{
component: 'Select',
macro: 'select',
},
{
component: 'SelectOrdinal',
macro: 'selectOrdinal',
},
].forEach((mapper) => {
root
.find(j.JSXElement, {
openingElement: { name: { name: mapper.component } }
})
.replaceWith((path) => {
const Node = path.value;

const valueProp = Node.openingElement.attributes.filter(
(obj) => obj.name.name === "value"
)[0];
const propsToObject = j.objectExpression(
Node.openingElement.attributes
.filter(el => el.name.name !== "value")
.map(
(obj) => j.property(
"init",
j.identifier(obj.name.name),
j.literal(obj.value.value)
)
)
)

let ast = null;
// format options are not required so
if (!propsToObject.properties.length) {
ast = j.callExpression(j.identifier(mapper.macro), [
valueProp.value.expression,
]);
} else {
ast = j.callExpression(j.identifier(mapper.macro), [
valueProp.value.expression,
propsToObject
]);
}

// if someone uses the components inside ternaries we can't add {number()}, must be just number()
if (path.parentPath.value.type === "ConditionalExpression" || path.parentPath.value.type === "VariableDeclarator") {
return ast
}

// if is a direct return, just add parenthesis
if (path.parentPath.value.type === "ReturnStatement") {
return j.parenthesizedExpression(ast);
}

// if not, just add {}
return j.jsxExpressionContainer(ast);
});
})
}
30 changes: 23 additions & 7 deletions transforms/v2-to-v3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ function changeJsxToCoreDeprecatedFuncs(root, j: JSCodeshift) {
[
{
component: "DateFormat",
macro: "date"
macro: "i18n.date"
},
{
component: "NumberFormat",
macro: "number"
macro: "i18n.number"
}
].forEach(mapper => {
root
Expand Down Expand Up @@ -60,7 +60,17 @@ function changeJsxToCoreDeprecatedFuncs(root, j: JSCodeshift) {
}

// if someone uses the components inside ternaries we can't add {number()}, must be just number()
return path.parentPath.value.type === "ConditionalExpression" ? ast : j.jsxExpressionContainer(ast);
if (path.parentPath.value.type === "ConditionalExpression" || path.parentPath.value.type === "VariableDeclarator") {
return ast
}

// if is a direct return, just add parenthesis
if (path.parentPath.value.type === "ReturnStatement") {
return j.parenthesizedExpression(ast);
}

// if not, just add {}
return j.jsxExpressionContainer(ast);
});
})

Expand All @@ -79,9 +89,13 @@ function changeReactImportToNewImports(root: Collection , j: JSCodeshift) {
}
});

migrateTo(root, linguiReactImports, j, "Plural", "Plural", "@lingui/macro");
migrateTo(root, linguiReactImports, j, "Select", "Select", "@lingui/macro");
migrateTo(root, linguiReactImports, j, "SelectOrdinal", "SelectOrdinal", "@lingui/macro");
migrateTo(root, linguiReactImports, j, "Trans", "Trans", "@lingui/macro");
migrateTo(root, linguiReactImports, j, "NumberFormat", "number", "@lingui/core");
migrateTo(root, linguiReactImports, j, "DateFormat", "date", "@lingui/core");

migrateTo(root, linguiReactImports, j, "NumberFormat", "i18n", "@lingui/core");
migrateTo(root, linguiReactImports, j, "DateFormat", "i18n", "@lingui/core");
}

/**
Expand All @@ -96,8 +110,8 @@ function changeFromMacroToCore(root: Collection , j: JSCodeshift) {
});

migrateTo(root, linguiMacroImports, j, "number", "number", "@lingui/core");
migrateTo(root, linguiMacroImports, j, "date", "date", "@lingui/core");
migrateTo(root, linguiMacroImports, j, "NumberFormat", "number", "@lingui/core");
migrateTo(root, linguiMacroImports, j, "date", "i18n", "@lingui/core");
migrateTo(root, linguiMacroImports, j, "NumberFormat", "i18n", "@lingui/core");
}

/**
Expand All @@ -120,8 +134,10 @@ function migrateTo(root, linguiReactImports, j, lookupImport, newLookupImport, n
value: newPackageName
}
});

linguiReactImports.forEach((path) => {
const node = path.value;
if (!node) return;
const transImportIndex = node.specifiers.findIndex((el) => el.imported.name === lookupImport);

if (transImportIndex !== -1) {
Expand Down
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"module": "commonjs",
"target": "es6",
"esModuleInterop": true,
"resolveJsonModule": true,
"jsx": "preserve"
},
"include": [
Expand Down

0 comments on commit e6ecd7e

Please sign in to comment.