Skip to content

Commit

Permalink
Merge pull request #528 from simplabs/parser-plugins
Browse files Browse the repository at this point in the history
Add custom plugin/extension support
  • Loading branch information
Mikek2252 authored Aug 26, 2022
2 parents 4ac1587 + be373b2 commit 1063d14
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 11 deletions.
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,28 @@ This example will try to find all `en.yaml` files in the different `translations
folders, but any patterns supported by [`globby`](https://www.npmjs.com/package/globby) are also
possible here.

### `babelParserPlugins` `extensions`

If your application uses doesn't parse correctly because it requires a specific babel plugin you can specifiy them in the config file under the key `babelParserPlugins` a list on plugins can be found [here](https://babeljs.io/docs/en/babel-parser#plugins).

For example if you would like typescript support you can specify the `typescript` plugin, although please note if the plugin introduces a new file extension you will also need to specifiy that in the `extensions` property. See the examples below.

Typescript example
```js
export default {
babelParserPlugins: ['typescript'],
extensions: ['.ts'],
};
```

Jsx example
```js
export default {
babelParserPlugins: ['jsx'],
extensions: ['.jsx'],
};
```

### `--fix`
If your application has a lot of unused translations you can run the command with
the `--fix` to remove them. Remember to double check your translations as dynamic
Expand Down
14 changes: 14 additions & 0 deletions __snapshots__/test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,20 @@ exports[`Test Fixtures no-issues 1`] = `

exports[`Test Fixtures no-issues 2`] = `Map {}`;

exports[`Test Fixtures plugin-config 1`] = `
"[1/4] 🔍 Finding JS and HBS files...
[2/4] 🔍 Searching for translations keys in JS and HBS files...
[3/4] ⚙️ Checking for unused translations...
[4/4] ⚙️ Checking for missing translations...
👏 No unused translations were found!
👏 No missing translations were found!
"
`;

exports[`Test Fixtures plugin-config 2`] = `Map {}`;

exports[`Test Fixtures remove-unused-translations 1`] = `
"[1/4] 🔍 Finding JS and HBS files...
[2/4] 🔍 Searching for translations keys in JS and HBS files...
Expand Down
7 changes: 7 additions & 0 deletions fixtures/plugin-config/app/controllers/application.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import Controller from '@ember/controller';

export default class ApplicationController extends Controller {
get foo() {
return this.intl.t('ts-translation');
}
}
1 change: 1 addition & 0 deletions fixtures/plugin-config/app/templates/application.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{t "hbs-translation"}}
2 changes: 2 additions & 0 deletions fixtures/plugin-config/translations/en.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ts-translation: "TS!"
hbs-translation: "HBS!"
33 changes: 22 additions & 11 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const traverse = require('@babel/traverse').default;
const Glimmer = require('@glimmer/syntax');
const Emblem = require('emblem').default;
const YAML = require('yaml');
const DEFAULT_EXTENSIONS = ['.js', '.hbs', '.emblem'];

async function run(rootDir, options = {}) {
let log = options.log || console.log;
Expand All @@ -27,11 +28,16 @@ async function run(rootDir, options = {}) {

let config = options.config || readConfig(rootDir);
let analyzeConcatExpression = options.analyzeConcatExpression || config.analyzeConcatExpression;
let analyzeOptions = { analyzeConcatExpression };
let userPlugins = config.babelParserPlugins || [];
let userExtensions = config.extensions || [];
userExtensions = userExtensions.map(extension =>
extension.startsWith('.') ? extension : `.${extension}`
);
let analyzeOptions = { analyzeConcatExpression, userPlugins, userExtensions };

log(`${step(1)} 🔍 Finding JS and HBS files...`);
let appFiles = await findAppFiles(rootDir);
let inRepoFiles = await findInRepoFiles(rootDir);
let appFiles = await findAppFiles(rootDir, userExtensions);
let inRepoFiles = await findInRepoFiles(rootDir, userExtensions);
let files = [...appFiles, ...inRepoFiles];

log(`${step(2)} 🔍 Searching for translations keys in JS and HBS files...`);
Expand Down Expand Up @@ -113,15 +119,20 @@ function readConfig(cwd) {
return config;
}

async function findAppFiles(cwd) {
return globby(['app/**/*.js', 'app/**/*.hbs', 'app/**/*.emblem'], { cwd });
async function findAppFiles(cwd, userExtensions) {
let extensions = [...DEFAULT_EXTENSIONS, ...userExtensions];
let pathsWithExtensions = extensions.map(extension => 'app/**/*' + extension);
return globby(pathsWithExtensions, { cwd });
}

async function findInRepoFiles(cwd) {
async function findInRepoFiles(cwd, userExtensions) {
let inRepoPaths = findInRepoPaths(cwd);
let inRepoFolders = joinPaths(inRepoPaths, ['addon', 'app']);

return globby(joinPaths(inRepoFolders, ['**/*.js', '**/*.hbs', '**/*.emblem']), { cwd });
let extensions = [...DEFAULT_EXTENSIONS, ...userExtensions];
let pathsWithExtensions = extensions.map(extension => `**/*${extension}`);

return globby(joinPaths(inRepoFolders, pathsWithExtensions), { cwd });
}

async function findOwnTranslationFiles(cwd, config) {
Expand Down Expand Up @@ -188,8 +199,8 @@ async function analyzeFile(cwd, file, options) {
let content = fs.readFileSync(`${cwd}/${file}`, 'utf8');
let extension = path.extname(file).toLowerCase();

if (extension === '.js') {
return analyzeJsFile(content, options);
if (['.js', ...options.userExtensions].includes(extension)) {
return analyzeJsFile(content, options.userPlugins);
} else if (extension === '.hbs') {
return analyzeHbsFile(content, options);
} else if (extension === '.emblem') {
Expand All @@ -200,13 +211,13 @@ async function analyzeFile(cwd, file, options) {
}
}

async function analyzeJsFile(content) {
async function analyzeJsFile(content, userPlugins) {
let translationKeys = new Set();

// parse the JS file
let ast = BabelParser.parse(content, {
sourceType: 'module',
plugins: ['decorators-legacy', 'dynamicImport', 'classProperties'],
plugins: ['decorators-legacy', 'dynamicImport', 'classProperties', ...userPlugins],
});

// find translation keys in the syntax tree
Expand Down
4 changes: 4 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ describe('Test Fixtures', () => {
'chosen-translations': {
translationFiles: ['**/en.yaml'],
},
'plugin-config': {
babelParserPlugins: ['typescript'],
extensions: ['.ts'],
},
};

beforeEach(() => {
Expand Down

0 comments on commit 1063d14

Please sign in to comment.