(bugfix) extract strings encapsulated with backticks. Closes #139

This commit is contained in:
Kim Biesbjerg 2019-08-26 12:29:52 +02:00
parent e1bb5bfd02
commit 24ebd8f428
6 changed files with 31 additions and 13 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "@biesbjerg/ngx-translate-extract", "name": "@biesbjerg/ngx-translate-extract",
"version": "3.0.3", "version": "3.0.4",
"description": "Extract strings from projects using ngx-translate", "description": "Extract strings from projects using ngx-translate",
"main": "dist/index.js", "main": "dist/index.js",
"typings": "dist/index.d.ts", "typings": "dist/index.d.ts",

View File

@ -4,7 +4,8 @@ import {
CallExpression, CallExpression,
Node, Node,
SyntaxKind, SyntaxKind,
StringLiteral StringLiteral,
NoSubstitutionTemplateLiteral
} from 'typescript'; } from 'typescript';
export abstract class AbstractAstParser { export abstract class AbstractAstParser {
@ -24,19 +25,23 @@ export abstract class AbstractAstParser {
} }
const firstArg = callNode.arguments[0]; const firstArg = callNode.arguments[0];
return this.findNodes(firstArg, SyntaxKind.StringLiteral)
.map((node: StringLiteral) => node.text); return this.findNodes(firstArg, [
SyntaxKind.StringLiteral,
SyntaxKind.NoSubstitutionTemplateLiteral
])
.map((node: StringLiteral | NoSubstitutionTemplateLiteral) => node.text);
} }
/** /**
* Find all child nodes of a kind * Find all child nodes of a kind
*/ */
protected findNodes(node: Node, kind: SyntaxKind): Node[] { protected findNodes(node: Node, kinds: SyntaxKind[]): Node[] {
const childrenNodes: Node[] = node.getChildren(this.sourceFile); const childrenNodes: Node[] = node.getChildren(this.sourceFile);
const initialValue: Node[] = node.kind === kind ? [node] : []; const initialValue: Node[] = kinds.includes(node.kind) ? [node] : [];
return childrenNodes.reduce((result: Node[], childNode: Node) => { return childrenNodes.reduce((result: Node[], childNode: Node) => {
return result.concat(this.findNodes(childNode, kind)); return result.concat(this.findNodes(childNode, kinds));
}, initialValue); }, initialValue);
} }

View File

@ -38,7 +38,7 @@ export class FunctionParser extends AbstractAstParser implements ParserInterface
node = this.sourceFile; node = this.sourceFile;
} }
let callNodes = this.findNodes(node, SyntaxKind.CallExpression) as CallExpression[]; let callNodes = this.findNodes(node, [SyntaxKind.CallExpression]) as CallExpression[];
callNodes = callNodes callNodes = callNodes
.filter(callNode => { .filter(callNode => {
// Only call expressions with arguments // Only call expressions with arguments

View File

@ -89,14 +89,14 @@ export class ServiceParser extends AbstractAstParser implements ParserInterface
* Find class nodes * Find class nodes
*/ */
protected findClassNodes(node: Node): ClassDeclaration[] { protected findClassNodes(node: Node): ClassDeclaration[] {
return this.findNodes(node, SyntaxKind.ClassDeclaration) as ClassDeclaration[]; return this.findNodes(node, [SyntaxKind.ClassDeclaration]) as ClassDeclaration[];
} }
/** /**
* Find constructor * Find constructor
*/ */
protected findConstructorNode(node: ClassDeclaration): ConstructorDeclaration { protected findConstructorNode(node: ClassDeclaration): ConstructorDeclaration {
const constructorNodes = this.findNodes(node, SyntaxKind.Constructor) as ConstructorDeclaration[]; const constructorNodes = this.findNodes(node, [SyntaxKind.Constructor]) as ConstructorDeclaration[];
if (constructorNodes) { if (constructorNodes) {
return constructorNodes[0]; return constructorNodes[0];
} }
@ -106,7 +106,7 @@ export class ServiceParser extends AbstractAstParser implements ParserInterface
* Find all calls to TranslateService methods * Find all calls to TranslateService methods
*/ */
protected findCallNodes(node: Node, propertyIdentifier: string): CallExpression[] { protected findCallNodes(node: Node, propertyIdentifier: string): CallExpression[] {
let callNodes = this.findNodes(node, SyntaxKind.CallExpression) as CallExpression[]; let callNodes = this.findNodes(node, [SyntaxKind.CallExpression]) as CallExpression[];
callNodes = callNodes callNodes = callNodes
.filter(callNode => { .filter(callNode => {
// Only call expressions with arguments // Only call expressions with arguments

View File

@ -122,6 +122,19 @@ describe('ServiceParser', () => {
expect(key).to.deep.equal(['Hello', 'World']); expect(key).to.deep.equal(['Hello', 'World']);
}); });
it('should extract string arrays encapsulated in backticks', () => {
const contents = `
@Component({ })
export class AppComponent {
public constructor(protected _translateService: TranslateService) { }
public test() {
this._translateService.get([\`Hello\`, \`World\`]);
}
`;
const keys = parser.extract(contents, componentFilename).keys();
expect(keys).to.deep.equal(['Hello', 'World']);
});
it('should not extract strings in get()/instant()/stream() methods of other services', () => { it('should not extract strings in get()/instant()/stream() methods of other services', () => {
const contents = ` const contents = `
@Component({ }) @Component({ })

View File

@ -5,10 +5,10 @@
"noImplicitAny": true, "noImplicitAny": true,
"removeComments": true, "removeComments": true,
"declaration": true, "declaration": true,
"target": "es6", "target": "es2015",
"lib": [ "lib": [
"dom", "dom",
"es2015" "es2018"
], ],
"module": "commonjs", "module": "commonjs",
"outDir": "./dist/", "outDir": "./dist/",