Skip to content

Commit

Permalink
fix(generate): inject changeLanguage statement after imports and befo…
Browse files Browse the repository at this point in the history
…re frontmatter logic

fixes #23
  • Loading branch information
yassinedoghri committed Aug 27, 2022
1 parent bb7ab0f commit 4d74e0b
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 33 deletions.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"test:coverage": "npm test -- --coverage",
"preview": "astro preview",
"build": "./build.cjs && npm run typecheck:emit && npm link .",
"lint": "eslint --ext js,ts,mts src",
"lint": "eslint --ext js,cjs,ts .",
"prettier": "prettier --check --ignore-path .gitignore .",
"prettier:fix": "prettier --write --ignore-path .gitignore .",
"typecheck": "tsc --noEmit",
Expand Down Expand Up @@ -110,8 +110,8 @@
"typescript": "^4.8.2"
},
"lint-staged": {
"*.js": "eslint --ext js,ts,mts --cache --fix",
"*.{js,css,md}": "prettier --write"
"*.{js,cjs,ts}": "eslint --ext js,cjs,ts . --cache --fix",
"*.{js,cjs,ts,astro,css,md}": "prettier --write"
},
"config": {
"commitizen": {
Expand Down
20 changes: 10 additions & 10 deletions src/__tests__/cli/transformer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,61 +13,61 @@ describe("transformer(...)", () => {
name: "with no i18next import",
actual: ``,
expected:
'import { changeLanguage } from "i18next";\n\nchangeLanguage("fr");\n',
'import { changeLanguage } from "i18next";\n\nchangeLanguage("fr");\n\n',
},
{
name: "with i18next import",
actual: `import i18next from "i18next";`,
expected:
'import i18next, { changeLanguage } from "i18next";\n\nchangeLanguage("fr");\n',
'import i18next, { changeLanguage } from "i18next";\n\nchangeLanguage("fr");\n\n',
},
{
name: "with i18next import + named imports",
actual: `import {t} from "i18next";`,
expected:
'import { t, changeLanguage } from "i18next";\n\nchangeLanguage("fr");\n',
'import { t, changeLanguage } from "i18next";\n\nchangeLanguage("fr");\n\n',
},
{
name: "with i18next import + named imports + language switch",
actual: `import { t, changeLanguage } from "i18next";changeLanguage("en");\n`,
expected:
'import { t, changeLanguage } from "i18next";\n\nchangeLanguage("fr");\n',
'import { t, changeLanguage } from "i18next";\n\nchangeLanguage("fr");\n\n',
},
{
name: "with i18next import + global import + named imports + language switch",
actual: `import i18next, { t, changeLanguage } from "i18next";changeLanguage("en");`,
expected:
'import i18next, { t, changeLanguage } from "i18next";\n\nchangeLanguage("fr");\n',
'import i18next, { t, changeLanguage } from "i18next";\n\nchangeLanguage("fr");\n\n',
},
{
name: "with changeLanguage being called from i18next import",
actual: `import i18next from "i18next";i18next.changeLanguage("en");`,
expected:
'import i18next, { changeLanguage } from "i18next";\n\nchangeLanguage("fr");\n',
'import i18next, { changeLanguage } from "i18next";\n\nchangeLanguage("fr");\n\n',
},
{
name: "with changeLanguage being called from i18next import + named imports",
actual: `import i18next, { changeLanguage } from "i18next";i18next.changeLanguage("en");`,
expected:
'import i18next, { changeLanguage } from "i18next";\n\nchangeLanguage("fr");\n',
'import i18next, { changeLanguage } from "i18next";\n\nchangeLanguage("fr");\n\n',
},
{
name: "with other imports",
actual: `import foo from "foo";\nimport bar from "bar";\nimport {baz} from "baz";\nimport { changeLanguage } from "i18next";changeLanguage("en");`,
expected:
'import foo from "foo";\nimport bar from "bar";\nimport { baz } from "baz";\nimport { changeLanguage } from "i18next";\n\nchangeLanguage("fr");\n',
'import foo from "foo";\nimport bar from "bar";\nimport { baz } from "baz";\nimport { changeLanguage } from "i18next";\n\nchangeLanguage("fr");\n\n',
},
{
name: "with logic after imports",
actual: `import { changeLanguage } from "i18next";\n\nconst a = 1 + 2;\nchangeLanguage("en");`,
expected:
'import { changeLanguage } from "i18next";\nconst a = 1 + 2;\n\nchangeLanguage("fr");\n',
'import { changeLanguage } from "i18next";\n\nchangeLanguage("fr");\n\nconst a = 1 + 2;\n',
},
{
name: "with relative imports",
actual: `import Foo from "../Foo.astro";\nimport Bar from "../../Bar.astro";\nimport { baz } from "./baz";`,
expected:
'import { changeLanguage } from "i18next";\nimport Foo from "../../Foo.astro";\nimport Bar from "../../../Bar.astro";\nimport { baz } from "../baz";\n\nchangeLanguage("fr");\n',
'import { changeLanguage } from "i18next";\nimport Foo from "../../Foo.astro";\nimport Bar from "../../../Bar.astro";\nimport { baz } from "../baz";\n\nchangeLanguage("fr");\n\n',
},
];

Expand Down
58 changes: 38 additions & 20 deletions src/cli/transformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ export const transformer: ts.TransformerFactory<ts.SourceFile> =
if (!node.importClause.namedBindings) {
return factory.updateImportDeclaration(
node,
node.decorators,
node.modifiers,
factory.createImportClause(
node.importClause.isTypeOnly,
Expand Down Expand Up @@ -54,7 +53,6 @@ export const transformer: ts.TransformerFactory<ts.SourceFile> =
// import changeLanguage function in i18next import declaration
return factory.updateImportDeclaration(
node,
node.decorators,
node.modifiers,
factory.updateImportClause(
node.importClause,
Expand Down Expand Up @@ -85,7 +83,6 @@ export const transformer: ts.TransformerFactory<ts.SourceFile> =
) {
return factory.updateImportDeclaration(
node,
node.decorators,
node.modifiers,
node.importClause,
factory.createStringLiteral(
Expand Down Expand Up @@ -115,23 +112,11 @@ export const transformer: ts.TransformerFactory<ts.SourceFile> =

let visitedNode = ts.visitNode(rootNode, visit);

let statements: ts.NodeArray<ts.Statement> = factory.createNodeArray([
...visitedNode.statements,
// append the changeLanguageStatement after a new line
factory.createIdentifier("\n") as unknown as ts.Statement,
factory.createExpressionStatement(
factory.createCallExpression(
factory.createIdentifier("changeLanguage"),
undefined,
[factory.createStringLiteral(language as string)]
)
),
]);
const statements = [...visitedNode.statements];

if (!doesI18nextImportExist) {
statements = factory.createNodeArray([
statements.unshift(
factory.createImportDeclaration(
undefined,
undefined,
factory.createImportClause(
false,
Expand All @@ -146,11 +131,44 @@ export const transformer: ts.TransformerFactory<ts.SourceFile> =
),
factory.createStringLiteral("i18next"),
undefined
),
...statements,
]);
)
);
}

// append the changeLanguage statement after imports

// get a boolean array with values telling whether or not a statement is an import
const importDeclarationsMap = statements.map((statement) =>
ts.isImportDeclaration(statement)
);

const lastIndexOfImportDeclaration =
importDeclarationsMap.lastIndexOf(true);

// insert changeLanguage statement after the imports
// and surrounded by line breaks
statements.splice(
lastIndexOfImportDeclaration + 1,
0,
factory.createIdentifier("\n") as unknown as ts.Statement
);
statements.splice(
lastIndexOfImportDeclaration + 1,
0,
factory.createExpressionStatement(
factory.createCallExpression(
factory.createIdentifier("changeLanguage"),
undefined,
[factory.createStringLiteral(language as string)]
)
)
);
statements.splice(
lastIndexOfImportDeclaration + 1,
0,
factory.createIdentifier("\n") as unknown as ts.Statement
);

visitedNode = factory.updateSourceFile(
visitedNode,
statements,
Expand Down

0 comments on commit 4d74e0b

Please sign in to comment.