diff --git a/README.md b/README.md index 08bae63..ea3c078 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,8 @@ Options: -d, --dir [DIR] Directory path you would like to extract strings from (Default is current directory) -o, --output [DIR] Directory path you would like to save extracted strings (Default is current directory/template.json) - -f, --format [VALUE] Output format. VALUE must be either [json|pot] (Default is json) + -f, --format [VALUE] Output format. VALUE must be either + [json|namespaced-json|pot] (Default is json) -r, --replace BOOLEAN Replace the contents of output file if it exists (Merges by default) -s, --sort BOOLEAN Sort translations in the output file in alphabetical diff --git a/package.json b/package.json index 82e82af..0f74428 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@biesbjerg/ng2-translate-extract", - "version": "0.4.0", + "version": "0.5.0", "description": "Extract strings from projects using ng2-translate", "main": "dist/index.js", "typings": "dist/index.d.ts", @@ -60,6 +60,7 @@ "fs": "0.0.1-security", "gettext-parser": "1.2.1", "glob": "7.1.1", - "path": "0.12.7" + "path": "0.12.7", + "flat": "2.0.1" } } diff --git a/src/cli/extract.ts b/src/cli/extract.ts index 603e118..761675f 100755 --- a/src/cli/extract.ts +++ b/src/cli/extract.ts @@ -4,7 +4,9 @@ import { ParserInterface } from '../parsers/parser.interface'; import { PipeParser } from '../parsers/pipe.parser'; import { DirectiveParser } from '../parsers/directive.parser'; import { ServiceParser } from '../parsers/service.parser'; +import { CompilerInterface } from '../compilers/compiler.interface'; import { JsonCompiler } from '../compilers/json.compiler'; +import { NamespacedJsonCompiler } from '../compilers/namespaced-json.compiler'; import { PoCompiler } from '../compilers/po.compiler'; import * as fs from 'fs'; @@ -14,17 +16,45 @@ import * as cli from 'cli'; const options = cli.parse({ dir: ['d', 'Path you would like to extract strings from', 'dir', process.env.PWD], output: ['o', 'Path you would like to save extracted strings to', 'dir', process.env.PWD], - format: ['f', 'Output format', ['json', 'pot'], 'json'], + format: ['f', 'Output format', ['json', 'namespaced-json', 'pot'], 'json'], replace: ['r', 'Replace the contents of output file if it exists (Merges by default)', 'boolean', false], sort: ['s', 'Sort translations in the output file in alphabetical order', 'boolean', false], clean: ['c', 'Remove obsolete strings when merging', 'boolean', false] }); +const patterns: string[] = [ + '/**/*.html', + '/**/*.ts', + '/**/*.js' +]; +const parsers: ParserInterface[] = [ + new PipeParser(), + new DirectiveParser(), + new ServiceParser() +]; + +let compiler: CompilerInterface; +let ext: string; +switch (options.format) { + case 'pot': + compiler = new PoCompiler(); + ext = 'pot'; + break; + case 'json': + compiler = new JsonCompiler(); + ext = 'json'; + break; + case 'namespaced-json': + compiler = new NamespacedJsonCompiler(); + ext = 'json'; + break; +} + const normalizedDir: string = path.resolve(options.dir); const normalizedOutput: string = path.resolve(options.output); let outputDir: string = normalizedOutput; -let outputFilename: string = `template.${options.format}`; +let outputFilename: string = `template.${ext}`; if (!fs.existsSync(normalizedOutput) || !fs.statSync(normalizedOutput).isDirectory()) { outputDir = path.dirname(normalizedOutput); outputFilename = path.basename(normalizedOutput); @@ -37,21 +67,6 @@ const outputPath: string = path.join(outputDir, outputFilename); } }); -let compiler = new JsonCompiler(); -if (options.format === 'pot') { - compiler = new PoCompiler(); -} -const parsers: ParserInterface[] = [ - new PipeParser(), - new DirectiveParser(), - new ServiceParser() -]; -const patterns: string[] = [ - '/**/*.html', - '/**/*.ts', - '/**/*.js' -]; - try { const extractor: Extractor = new Extractor(parsers, patterns); cli.info(`Extracting strings from '${normalizedDir}'`); diff --git a/src/compilers/namespaced-json.compiler.ts b/src/compilers/namespaced-json.compiler.ts new file mode 100644 index 0000000..45d1076 --- /dev/null +++ b/src/compilers/namespaced-json.compiler.ts @@ -0,0 +1,18 @@ +import { CompilerInterface } from './compiler.interface'; +import { TranslationCollection } from '../utils/translation.collection'; + +import * as flat from 'flat'; + +export class NamespacedJsonCompiler implements CompilerInterface { + + public compile(collection: TranslationCollection): string { + const values = flat.unflatten(collection.values); + return JSON.stringify(values, null, '\t'); + } + + public parse(contents: string): TranslationCollection { + const values = flat.flatten(JSON.parse(contents)); + return new TranslationCollection(values); + } + +} diff --git a/src/declarations.d.ts b/src/declarations.d.ts index efd483a..4eaeade 100644 --- a/src/declarations.d.ts +++ b/src/declarations.d.ts @@ -1,2 +1,3 @@ declare module 'cli'; +declare module 'flat'; declare module 'gettext-parser'; diff --git a/tests/compilers/namespaced-compiler.spec.ts b/tests/compilers/namespaced-compiler.spec.ts new file mode 100644 index 0000000..6801215 --- /dev/null +++ b/tests/compilers/namespaced-compiler.spec.ts @@ -0,0 +1,38 @@ +import { expect } from 'chai'; + +import { TranslationCollection } from '../../src/utils/translation.collection'; +import { NamespacedJsonCompiler } from '../../src/compilers/namespaced-json.compiler'; + +describe('NamespacedJsonCompiler', () => { + + let compiler: NamespacedJsonCompiler; + + beforeEach(() => { + compiler = new NamespacedJsonCompiler(); + }); + + it('should flatten keys on parse', () => { + const contents = ` + { + "NAMESPACE": { + "KEY": { + "FIRST_KEY": "", + "SECOND_KEY": "VALUE" + } + } + } + `; + const collection: TranslationCollection = compiler.parse(contents); + expect(collection.values).to.deep.equal({'NAMESPACE.KEY.FIRST_KEY': '', 'NAMESPACE.KEY.SECOND_KEY': 'VALUE' }); + }); + + it('should unflatten keys on compile', () => { + const collection = new TranslationCollection({ + 'NAMESPACE.KEY.FIRST_KEY': '', + 'NAMESPACE.KEY.SECOND_KEY': 'VALUE' + }); + const result: string = compiler.compile(collection); + expect(result).to.equal('{\n\t"NAMESPACE": {\n\t\t"KEY": {\n\t\t\t"FIRST_KEY": "",\n\t\t\t"SECOND_KEY": "VALUE"\n\t\t}\n\t}\n}'); + }); + +});