Skip to content

Commit

Permalink
feat: Add support for the ngx-translate _() marker function (#57)
Browse files Browse the repository at this point in the history
Closes: #56
  • Loading branch information
pmpak authored Nov 18, 2024
1 parent 5d47e23 commit 3ddb57a
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 5 deletions.
15 changes: 13 additions & 2 deletions src/parsers/marker.parser.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import { ParserInterface } from './parser.interface.js';
import { TranslationCollection } from '../utils/translation.collection.js';
import { getNamedImportAlias, findFunctionCallExpressions, getStringsFromExpression, getAST } from '../utils/ast-helpers.js';
import { SourceFile } from 'typescript';

const MARKER_MODULE_NAME = 'ngx-translate-extract-marker';
const MARKER_MODULE_NAME = new RegExp('ngx-translate-extract-marker');
const MARKER_IMPORT_NAME = 'marker';
const NGX_TRANSLATE_MARKER_MODULE_NAME = '@ngx-translate/core';
const NGX_TRANSLATE_MARKER_IMPORT_NAME = '_';

export class MarkerParser implements ParserInterface {
public extract(source: string, filePath: string): TranslationCollection | null {
const sourceFile = getAST(source, filePath);

const markerImportName = getNamedImportAlias(sourceFile, MARKER_IMPORT_NAME, new RegExp(MARKER_MODULE_NAME));
const markerImportName = this.getMarkerImportNameFromSource(sourceFile);
if (!markerImportName) {
return null;
}
Expand All @@ -27,4 +30,12 @@ export class MarkerParser implements ParserInterface {
});
return collection;
}

private getMarkerImportNameFromSource(sourceFile: SourceFile): string {
const markerImportName =
getNamedImportAlias(sourceFile, MARKER_IMPORT_NAME, MARKER_MODULE_NAME) ||
getNamedImportAlias(sourceFile, NGX_TRANSLATE_MARKER_IMPORT_NAME, NGX_TRANSLATE_MARKER_MODULE_NAME);

return markerImportName ?? '';
}
}
58 changes: 55 additions & 3 deletions tests/parsers/marker.parser.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,16 +75,68 @@ describe('MarkerParser', () => {
it('should not break after bracket syntax casting', () => {
const contents = `
import { marker } from '@colsen1991/ngx-translate-extract-marker';
marker('hello');
const input: unknown = 'hello';
const input: unknown = 'hello';
const myNiceVar1 = input as string;
marker('hello.after.as.syntax');
const myNiceVar2 = <string>input;
marker('hello.after.bracket.syntax');
`;
const keys = parser.extract(contents, componentFilename).keys();
expect(keys).to.deep.equal(['hello', 'hello.after.as.syntax', 'hello.after.bracket.syntax']);
});

describe('marker from @ngx-translate/core', () => {
it('should extract strings using marker (_) function', () => {
const contents = `
import {_} from '@ngx-translate/core';
_('Hello world');
_(['I', 'am', 'extracted']);
otherFunction('But I am not');
_(message || 'binary expression');
_(message ? message : 'conditional operator');
_('FOO.bar');
`;
const keys = parser.extract(contents, componentFilename)?.keys();
expect(keys).to.deep.equal(['Hello world', 'I', 'am', 'extracted', 'binary expression', 'conditional operator', 'FOO.bar']);
});

it('should extract strings using an alias function', () => {
const contents = `
import {_ as marker} from '@ngx-translate/core';
marker('Hello world');
marker(['I', 'am', 'extracted']);
otherFunction('But I am not');
marker(message || 'binary expression');
marker(message ? message : 'conditional operator');
marker('FOO.bar');
`;
const keys = parser.extract(contents, componentFilename)?.keys();
expect(keys).to.deep.equal(['Hello world', 'I', 'am', 'extracted', 'binary expression', 'conditional operator', 'FOO.bar']);
});

it('should extract split strings', () => {
const contents = `
import {_} from '@ngx-translate/core';
_('Hello ' + 'world');
_('This is a ' + 'very ' + 'very ' + 'very ' + 'very ' + 'long line.');
_('Mix ' + \`of \` + 'different ' + \`types\`);
`;
const keys = parser.extract(contents, componentFilename).keys();
expect(keys).to.deep.equal(['Hello world', 'This is a very very very very long line.', 'Mix of different types']);
});

it('should extract split strings while keeping html tags', () => {
const contents = `
import {_} from '@ngx-translate/core';
_('Hello ' + 'world');
_('This <em>is</em> a ' + 'very ' + 'very ' + 'very ' + 'very ' + 'long line.');
_('Mix ' + \`of \` + 'different ' + \`types\`);
`;
const keys = parser.extract(contents, componentFilename).keys();
expect(keys).to.deep.equal(['Hello world', 'This <em>is</em> a very very very very long line.', 'Mix of different types']);
});
})
});

0 comments on commit 3ddb57a

Please sign in to comment.