From 4d74e0b3d1d03c40ca9090b82fb4d171cd4b84a0 Mon Sep 17 00:00:00 2001 From: Yassine Doghri Date: Sat, 27 Aug 2022 15:10:44 +0000 Subject: [PATCH] fix(generate): inject changeLanguage statement after imports and before frontmatter logic fixes #23 --- package.json | 6 +-- src/__tests__/cli/transformer.test.ts | 20 ++++----- src/cli/transformer.ts | 58 ++++++++++++++++++--------- 3 files changed, 51 insertions(+), 33 deletions(-) diff --git a/package.json b/package.json index 883e29d..7d6f31f 100644 --- a/package.json +++ b/package.json @@ -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", @@ -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": { diff --git a/src/__tests__/cli/transformer.test.ts b/src/__tests__/cli/transformer.test.ts index 5fad4a4..393a311 100644 --- a/src/__tests__/cli/transformer.test.ts +++ b/src/__tests__/cli/transformer.test.ts @@ -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', }, ]; diff --git a/src/cli/transformer.ts b/src/cli/transformer.ts index c2d9b7b..6b6412e 100644 --- a/src/cli/transformer.ts +++ b/src/cli/transformer.ts @@ -26,7 +26,6 @@ export const transformer: ts.TransformerFactory = if (!node.importClause.namedBindings) { return factory.updateImportDeclaration( node, - node.decorators, node.modifiers, factory.createImportClause( node.importClause.isTypeOnly, @@ -54,7 +53,6 @@ export const transformer: ts.TransformerFactory = // import changeLanguage function in i18next import declaration return factory.updateImportDeclaration( node, - node.decorators, node.modifiers, factory.updateImportClause( node.importClause, @@ -85,7 +83,6 @@ export const transformer: ts.TransformerFactory = ) { return factory.updateImportDeclaration( node, - node.decorators, node.modifiers, node.importClause, factory.createStringLiteral( @@ -115,23 +112,11 @@ export const transformer: ts.TransformerFactory = let visitedNode = ts.visitNode(rootNode, visit); - let statements: ts.NodeArray = 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, @@ -146,11 +131,44 @@ export const transformer: ts.TransformerFactory = ), 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,